diff --git a/src/Analysis/Engine/Impl/AnalysisValueSetExtensions.cs b/src/Analysis/Engine/Impl/AnalysisValueSetExtensions.cs
index 3ea088976..bd7d67316 100644
--- a/src/Analysis/Engine/Impl/AnalysisValueSetExtensions.cs
+++ b/src/Analysis/Engine/Impl/AnalysisValueSetExtensions.cs
@@ -218,7 +218,7 @@ internal static AnalysisValue GetUnionType(this IAnalysisSet types) {
/// Gets instance representations of all members of the set.
///
public static IAnalysisSet GetInstanceType(this IAnalysisSet types)
- => AnalysisSet.Create(types.SelectMany(ns => (ns.PythonType as IPythonType2)?.IsClass == true ? ns : ns.GetInstanceType()));
+ => AnalysisSet.Create(types.SelectMany(ns => ns.PythonType?.IsTypeFactory == true ? ns : ns.GetInstanceType()));
public static bool IsUnknown(this IAnalysisSet res) {
return res == null ||
diff --git a/src/Analysis/Engine/Impl/Analyzer/DDG.cs b/src/Analysis/Engine/Impl/Analyzer/DDG.cs
index a579ff4c0..a8a3bca6b 100644
--- a/src/Analysis/Engine/Impl/Analyzer/DDG.cs
+++ b/src/Analysis/Engine/Impl/Analyzer/DDG.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.
diff --git a/src/Analysis/Engine/Impl/Definitions/IOverloadResult.cs b/src/Analysis/Engine/Impl/Definitions/IOverloadResult.cs
index 7fc3cbcba..0dde5f8cf 100644
--- a/src/Analysis/Engine/Impl/Definitions/IOverloadResult.cs
+++ b/src/Analysis/Engine/Impl/Definitions/IOverloadResult.cs
@@ -9,21 +9,40 @@
// 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.Diagnostics.CodeAnalysis;
namespace Microsoft.PythonTools.Analysis {
public interface IOverloadResult {
+ ///
+ /// Function name.
+ ///
string Name { get; }
+
+ ///
+ /// Function documentation.
+ ///
string Documentation { get; }
- [SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays",
- Justification = "breaking change")]
+
+ ///
+ /// First parameter if removed from the set.
+ /// Typically 'self' or 'cls'.
+ ///
+ ParameterResult FirstParameter { get; }
+
+ ///
+ /// Function parameters. First parameter may be removed, in which case
+ /// it is present as .
+ ///
ParameterResult[] Parameters { get; }
+
+ ///
+ /// Possible return types.
+ ///
IReadOnlyList ReturnType { get; }
}
}
diff --git a/src/Analysis/Engine/Impl/EmptyBuiltinModule.cs b/src/Analysis/Engine/Impl/EmptyBuiltinModule.cs
index 7e8d4b984..dab810cb8 100644
--- a/src/Analysis/Engine/Impl/EmptyBuiltinModule.cs
+++ b/src/Analysis/Engine/Impl/EmptyBuiltinModule.cs
@@ -16,14 +16,11 @@
using System.Collections.Generic;
using Microsoft.PythonTools.Interpreter;
+using Microsoft.PythonTools.Interpreter.Ast;
namespace Microsoft.PythonTools.Analysis {
- class EmptyBuiltinModule : IBuiltinPythonModule {
- private readonly string _name;
-
- public EmptyBuiltinModule(string name) {
- _name = name;
- }
+ class EmptyBuiltinModule : PythonModuleType, IBuiltinPythonModule {
+ public EmptyBuiltinModule(string name): base(name) { }
#region IBuiltinPythonModule Members
@@ -35,42 +32,12 @@ public IMember GetAnyMember(string name) {
#region IPythonModule Members
- public string Name {
- get { return _name; }
- }
-
public IEnumerable GetChildrenModules() {
yield break;
}
public void Imported(IModuleContext context) {
}
-
- public string Documentation {
- get { return string.Empty; }
- }
-
- #endregion
-
- #region IMemberContainer Members
-
- public IMember GetMember(IModuleContext context, string name) {
- return null;
- }
-
- public IEnumerable GetMemberNames(IModuleContext moduleContext) {
- yield break;
- }
-
#endregion
-
- #region IMember Members
-
- public PythonMemberType MemberType {
- get { return PythonMemberType.Module; }
- }
-
- #endregion
-
}
}
diff --git a/src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs b/src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs
index 0ffca1a5c..28a0337d0 100644
--- a/src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs
+++ b/src/Analysis/Engine/Impl/Infrastructure/Extensions/EnumerableExtensions.cs
@@ -23,31 +23,21 @@ static class EnumerableExtensions {
public static bool IsNullOrEmpty(this IEnumerable source)
=> source == null || !source.Any();
- public static T[] MaybeEnumerate(this T[] source) {
- return source ?? Array.Empty();
- }
+ public static T[] MaybeEnumerate(this T[] source) => source ?? Array.Empty();
- public static IEnumerable MaybeEnumerate(this IEnumerable source) {
- return source ?? Enumerable.Empty();
- }
+ public static IEnumerable MaybeEnumerate(this IEnumerable source) => source ?? Enumerable.Empty();
- private static T Identity(T source) {
- return source;
- }
+ private static T Identity(T source) => source;
- public static IEnumerable SelectMany(this IEnumerable> source) {
- return source.SelectMany(Identity);
- }
+ public static IEnumerable SelectMany(this IEnumerable> source) => source.SelectMany(Identity);
- public static IEnumerable Ordered(this IEnumerable source) {
- return source.OrderBy(Identity);
- }
+ public static IEnumerable Ordered(this IEnumerable source)
+ => source.OrderBy(Identity);
private static bool NotNull(T obj) where T : class => obj != null;
- public static IEnumerable WhereNotNull(this IEnumerable source) where T : class {
- return source.Where(NotNull);
- }
+ public static IEnumerable WhereNotNull(this IEnumerable source) where T : class
+ => source != null ? source.Where(NotNull) : Enumerable.Empty();
public static bool SetEquals(this IEnumerable source, IEnumerable other,
IEqualityComparer comparer = null) where T : class {
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisFunctionWalker.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisFunctionWalker.cs
index 9eecd8018..7316bce0c 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisFunctionWalker.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisFunctionWalker.cs
@@ -65,7 +65,9 @@ public void Walk() {
var self = GetSelf();
_selfType = (self as AstPythonConstant)?.Type as AstPythonType;
- _overload.ReturnTypes.AddRange(_scope.GetTypesFromAnnotation(Target.ReturnAnnotation).ExcludeDefault());
+ var annotationTypes = _scope.GetTypesFromAnnotation(Target.ReturnAnnotation).ExcludeDefault();
+ _overload.ReturnTypes.AddRange(annotationTypes);
+
_scope.PushScope();
// Declare self, if any
@@ -84,7 +86,10 @@ public void Walk() {
_scope.SetInScope(p.Name, value ?? _scope.UnknownType);
}
- Target.Walk(this);
+ // return type from the annotation always wins, no need to walk the body.
+ if (!annotationTypes.Any()) {
+ Target.Walk(this);
+ }
_scope.PopScope();
}
@@ -165,7 +170,8 @@ public override bool Walk(IfStatement node) {
if (name != null && typeName != null) {
var typeId = typeName.GetTypeId();
if (typeId != BuiltinTypeId.Unknown) {
- _scope.SetInScope(name, new AstPythonConstant(new AstPythonBuiltinType(typeName, typeId)));
+ _scope.SetInScope(name,
+ new AstPythonConstant(new AstPythonType(typeName, typeId)));
}
}
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisWalker.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisWalker.cs
index 42e47663d..b8d9582df 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisWalker.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstAnalysisWalker.cs
@@ -115,7 +115,7 @@ internal LocationInfo GetLoc(ClassDefinition node) {
private LocationInfo GetLoc(Node node) => _scope.GetLoc(node);
private IMember Clone(IMember member) =>
- member is IPythonMultipleMembers mm ? AstPythonMultipleMembers.Create(mm.Members) :
+ member is IPythonMultipleMembers mm ? AstPythonMultipleMembers.Create(mm.GetMembers()) :
member;
public override bool Walk(AssignmentStatement node) {
@@ -423,14 +423,18 @@ public override bool Walk(FunctionDefinition node) {
var dec = (node.Decorators?.Decorators).MaybeEnumerate().ExcludeDefault();
foreach (var d in dec) {
var obj = _scope.GetValueFromExpression(d);
+
+ var declaringType = obj as IPythonType;
+ var declaringModule = declaringType?.DeclaringModule;
+
if (obj == _interpreter.GetBuiltinType(BuiltinTypeId.Property)) {
- AddProperty(node);
+ AddProperty(node, declaringModule, declaringType);
return false;
}
- var mod = (obj as IPythonType)?.DeclaringModule ?? (obj as IPythonFunction)?.DeclaringModule;
- var name = (obj as IPythonType)?.Name ?? (obj as IPythonFunction)?.Name;
- if (mod?.Name == "abc" && name == "abstractproperty") {
- AddProperty(node);
+
+ var name = declaringType?.Name;
+ if (declaringModule?.Name == "abc" && name == "abstractproperty") {
+ AddProperty(node, declaringModule, declaringType);
return false;
}
}
@@ -450,10 +454,10 @@ public override bool Walk(FunctionDefinition node) {
return false;
}
- private void AddProperty(FunctionDefinition node) {
+ private void AddProperty(FunctionDefinition node, IPythonModule declaringModule, IPythonType declaringType) {
var existing = _scope.LookupNameInScopes(node.Name, NameLookupContext.LookupOptions.Local) as AstPythonProperty;
if (existing == null) {
- existing = new AstPythonProperty(_ast, node, GetLoc(node));
+ existing = new AstPythonProperty(node, declaringModule, declaringType, GetLoc(node));
_scope.SetInScope(node.Name, existing);
}
@@ -471,8 +475,8 @@ private IPythonFunctionOverload CreateFunctionOverload(NameLookupContext funcSco
.ToArray();
var overload = new AstPythonFunctionOverload(
- parameters,
- funcScope.GetLocOfName(node, node.NameExpression),
+ parameters,
+ funcScope.GetLocOfName(node, node.NameExpression),
node.ReturnAnnotation?.ToCodeString(_ast));
_functionWalkers.Add(new AstAnalysisFunctionWalker(funcScope, node, overload));
@@ -485,14 +489,13 @@ private static string GetDoc(SuiteStatement node) {
return ce?.Value as string;
}
- private AstPythonType CreateType(ClassDefinition node) {
- if (node == null) {
- throw new ArgumentNullException(nameof(node));
- }
- return CreateBuiltinTypes
- ? new AstPythonBuiltinType(node.Name, _module, node.StartIndex, GetDoc(node.Body as SuiteStatement), GetLoc(node))
- : new AstPythonType(node.Name, _module, node.StartIndex, GetDoc(node.Body as SuiteStatement), GetLoc(node));
+ private AstPythonClass CreateClass(ClassDefinition node) {
+ node = node ?? throw new ArgumentNullException(nameof(node));
+ return new AstPythonClass(node, _module,
+ GetDoc(node.Body as SuiteStatement), GetLoc(node),
+ CreateBuiltinTypes ? BuiltinTypeId.Unknown : BuiltinTypeId.Type); // built-ins set type later
}
+
private void CollectTopLevelDefinitions() {
var s = (_ast.Body as SuiteStatement).Statements.ToArray();
@@ -501,7 +504,7 @@ private void CollectTopLevelDefinitions() {
}
foreach (var node in s.OfType()) {
- _members[node.Name] = CreateType(node);
+ _members[node.Name] = CreateClass(node);
}
foreach (var node in s.OfType().Where(n => n.Right is NameExpression)) {
@@ -516,10 +519,12 @@ private void CollectTopLevelDefinitions() {
public override bool Walk(ClassDefinition node) {
var member = _scope.GetInScope(node.Name);
- var t = member as AstPythonType ??
- (member as IPythonMultipleMembers)?.Members.OfType().FirstOrDefault(pt => pt.StartIndex == node.StartIndex);
+ var t = member as AstPythonClass;
+ if (t == null && member is IPythonMultipleMembers mm) {
+ t = mm.GetMembers().OfType().FirstOrDefault(pt => pt.ClassDefinition.StartIndex == node.StartIndex);
+ }
if (t == null) {
- t = CreateType(node);
+ t = CreateClass(node);
_scope.SetInScope(node.Name, t);
}
@@ -549,7 +554,7 @@ public void ProcessFunctionDefinition(FunctionDefinition node) {
var existing = _scope.LookupNameInScopes(node.Name, NameLookupContext.LookupOptions.Local) as AstPythonFunction;
if (existing == null) {
var cls = _scope.GetInScope("__class__") as IPythonType;
- existing = new AstPythonFunction(_ast, _module, cls, node, GetLoc(node));
+ existing = new AstPythonFunction(node, _module, cls, GetLoc(node));
_scope.SetInScope(node.Name, existing);
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs
index 5d69d8afd..9ef20664a 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstBuiltinsPythonModule.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.
@@ -43,8 +43,7 @@ public override IMember GetMember(IModuleContext context, string name) {
public IMember GetAnyMember(string name) {
lock (_members) {
- IMember m;
- _members.TryGetValue(name, out m);
+ _members.TryGetValue(name, out var m);
return m;
}
}
@@ -96,13 +95,12 @@ protected override PythonWalker PrepareWalker(AstPythonInterpreter interpreter,
}
protected override void PostWalk(PythonWalker walker) {
- AstPythonBuiltinType boolType = null;
- AstPythonBuiltinType noneType = null;
+ IPythonType boolType = null;
+ IPythonType noneType = null;
foreach (BuiltinTypeId typeId in Enum.GetValues(typeof(BuiltinTypeId))) {
- if (_members.TryGetValue("__{0}__".FormatInvariant(typeId), out IMember m) && m is AstPythonBuiltinType biType) {
- if (typeId != BuiltinTypeId.Str &&
- typeId != BuiltinTypeId.StrIterator) {
+ if (_members.TryGetValue("__{0}__".FormatInvariant(typeId), out var m) && m is AstPythonType biType && biType.IsBuiltin) {
+ if (typeId != BuiltinTypeId.Str && typeId != BuiltinTypeId.StrIterator) {
biType.TrySetTypeId(typeId);
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstNestedPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstNestedPythonModule.cs
index 2d0f49853..ce9297a04 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstNestedPythonModule.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstNestedPythonModule.cs
@@ -22,19 +22,15 @@
using Microsoft.PythonTools.Analysis.Infrastructure;
namespace Microsoft.PythonTools.Interpreter.Ast {
- internal sealed class AstNestedPythonModule : IPythonModule, ILocatedMember {
- private readonly string _name;
+ internal sealed class AstNestedPythonModule : PythonModuleType, IPythonModule, ILocatedMember {
private readonly IPythonInterpreter _interpreter;
private IPythonModule _module;
- public AstNestedPythonModule(IPythonInterpreter interpreter, string fullName) {
+ public AstNestedPythonModule(IPythonInterpreter interpreter, string fullName) : base(fullName) {
_interpreter = interpreter ?? throw new ArgumentNullException(nameof(interpreter));
- _name = fullName ?? throw new ArgumentNullException(nameof(fullName));
}
- public string Name => MaybeModule?.Name ?? _name;
- public string Documentation => MaybeModule?.Documentation ?? string.Empty;
- public PythonMemberType MemberType => PythonMemberType.Module;
+ public override string Documentation => MaybeModule?.Documentation ?? string.Empty;
public IEnumerable Locations => ((MaybeModule as ILocatedMember)?.Locations).MaybeEnumerate();
public bool IsLoaded => MaybeModule != null;
@@ -46,13 +42,13 @@ private IPythonModule GetModule() {
return module;
}
- module = _interpreter.ImportModule(_name);
+ module = _interpreter.ImportModule(Name);
if (module != null) {
Debug.Assert(!(module is AstNestedPythonModule), "ImportModule should not return nested module");
}
if (module == null) {
- module = new SentinelModule(_name, false);
+ module = new SentinelModule(Name, false);
}
return Interlocked.CompareExchange(ref _module, module, null) ?? module;
@@ -60,9 +56,10 @@ private IPythonModule GetModule() {
public IEnumerable GetChildrenModules() => GetModule().GetChildrenModules();
- public IMember GetMember(IModuleContext context, string name) => GetModule().GetMember(context, name);
+ public override IMember GetMember(IModuleContext context, string name)
+ => GetModule().GetMember(context, name);
- public IEnumerable GetMemberNames(IModuleContext context) =>
+ public override IEnumerable GetMemberNames(IModuleContext context) =>
// TODO: Make GetMemberNames() faster than Imported()
GetModule().GetMemberNames(context);
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs
deleted file mode 100644
index 645a6b772..000000000
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBoundMethod.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-// Python Tools for Visual Studio
-// Copyright(c) Microsoft Corporation
-// All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the License); you may not use
-// this file except in compliance with the License. You may obtain a copy of the
-// License at http://www.apache.org/licenses/LICENSE-2.0
-//
-// 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.
-//
-// See the Apache Version 2.0 License for specific language governing
-// permissions and limitations under the License.
-
-using System.Collections.Generic;
-using Microsoft.PythonTools.Analysis;
-using Microsoft.PythonTools.Analysis.Infrastructure;
-
-namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonBoundMethod : IPythonBoundFunction, ILocatedMember {
- public AstPythonBoundMethod(IPythonFunction function, IPythonType selfType) {
- Function = function;
- SelfType = selfType;
- }
-
- public IPythonFunction Function { get; }
- public IPythonType SelfType { get; }
- public PythonMemberType MemberType => PythonMemberType.Method;
- public IEnumerable Locations => (Function as ILocatedMember)?.Locations.MaybeEnumerate();
- }
-}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBuiltinType.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBuiltinType.cs
deleted file mode 100644
index 4fb6e0f17..000000000
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonBuiltinType.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Python Tools for Visual Studio
-// Copyright(c) Microsoft Corporation
-// All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the License); you may not use
-// this file except in compliance with the License. You may obtain a copy of the
-// License at http://www.apache.org/licenses/LICENSE-2.0
-//
-// 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,
-// MERCHANTABILITY OR NON-INFRINGEMENT.
-//
-// See the Apache Version 2.0 License for specific language governing
-// permissions and limitations under the License.
-
-using System.Linq;
-using Microsoft.PythonTools.Analysis;
-
-namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonBuiltinType : AstPythonType {
- private BuiltinTypeId _typeId;
-
- public AstPythonBuiltinType(string name, BuiltinTypeId typeId)
- : base(name) {
- _typeId = typeId;
- }
-
- public AstPythonBuiltinType(
- string name,
- IPythonModule declModule,
- int startIndex,
- string doc,
- LocationInfo loc,
- BuiltinTypeId typeId = BuiltinTypeId.Unknown,
- bool isClass = false
- ) : base(name, declModule, startIndex, doc, loc, isClass) {
- _typeId = typeId == BuiltinTypeId.Unknown && isClass ? BuiltinTypeId.Type : typeId;
- }
-
- public bool TrySetTypeId(BuiltinTypeId typeId) {
- if (_typeId != BuiltinTypeId.Unknown) {
- return false;
- }
- _typeId = typeId;
- return true;
- }
-
- public override bool IsBuiltin => true;
- public override BuiltinTypeId TypeId => _typeId;
-
- public bool IsHidden => ContainsMember("__hidden__");
-
- ///
- /// Clones builtin type as class. Typically used in scenarios where method
- /// returns an object that acts like a class constructor, such as namedtuple.
- ///
- ///
- public AstPythonBuiltinType AsClass() {
- var clone = new AstPythonBuiltinType(Name, DeclaringModule, StartIndex, Documentation,
- Locations.OfType().FirstOrDefault(),
- TypeId == BuiltinTypeId.Unknown ? BuiltinTypeId.Type : TypeId, true);
- clone.AddMembers(Members, true);
- return clone;
- }
- }
-}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonClass.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonClass.cs
new file mode 100644
index 000000000..111028c6b
--- /dev/null
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonClass.cs
@@ -0,0 +1,183 @@
+// Python Tools for Visual Studio
+// Copyright(c) Microsoft Corporation
+// All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the License); you may not use
+// this file except in compliance with the License. You may obtain a copy of the
+// License at http://www.apache.org/licenses/LICENSE-2.0
+//
+// 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,
+// MERCHANTABILITY OR NON-INFRINGEMENT.
+//
+// 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;
+using Microsoft.PythonTools.Analysis;
+using Microsoft.PythonTools.Analysis.Infrastructure;
+using Microsoft.PythonTools.Parsing.Ast;
+
+namespace Microsoft.PythonTools.Interpreter.Ast {
+ class AstPythonClass : AstPythonType, IPythonClass {
+ protected static readonly IPythonModule NoDeclModule = new AstPythonModule();
+
+ private readonly object _lock = new object();
+
+ private IReadOnlyList _mro;
+ private readonly AsyncLocal _isProcessing = new AsyncLocal();
+
+ public AstPythonClass(
+ ClassDefinition classDefinition,
+ IPythonModule declaringModule,
+ string doc,
+ ILocationInfo loc,
+ BuiltinTypeId builtinTypeId = BuiltinTypeId.Type
+ ) : base(classDefinition.Name, declaringModule, doc, loc, builtinTypeId, false) {
+ ClassDefinition = classDefinition;
+ }
+
+ internal AstPythonClass(string name) : base(name, BuiltinTypeId.Type) { }
+
+ #region IPythonType
+ public override PythonMemberType MemberType => PythonMemberType.Class;
+
+ public override IMember GetMember(IModuleContext context, string name) {
+ IMember member;
+ lock (_lock) {
+ if (Members.TryGetValue(name, out member)) {
+ return member;
+ }
+
+ // Special case names that we want to add to our own Members dict
+ switch (name) {
+ case "__mro__":
+ member = AddMember(name, new AstPythonSequence(
+ (context as IPythonInterpreter)?.GetBuiltinType(BuiltinTypeId.Tuple),
+ DeclaringModule,
+ Mro,
+ (context as IPythonInterpreter)?.GetBuiltinType(BuiltinTypeId.TupleIterator)
+ ), true);
+ return member;
+ }
+ }
+ if (Push()) {
+ try {
+ foreach (var m in Mro.Reverse()) {
+ if (m == this) {
+ return member;
+ }
+ member = member ?? m.GetMember(context, name);
+ }
+ } finally {
+ Pop();
+ }
+ }
+ return null;
+ }
+ #endregion
+
+ #region IPythonClass
+ public ClassDefinition ClassDefinition { get; }
+ public IReadOnlyList Bases { get; private set; }
+
+ public IReadOnlyList Mro {
+ get {
+ lock (_lock) {
+ if (_mro != null) {
+ return _mro;
+ }
+ if (Bases == null) {
+ //Debug.Fail("Accessing Mro before SetBases has been called");
+ return new IPythonType[] { this };
+ }
+ _mro = new IPythonType[] { this };
+ _mro = CalculateMro(this);
+ return _mro;
+ }
+ }
+ }
+ #endregion
+
+ internal void SetBases(IPythonInterpreter interpreter, IEnumerable bases) {
+ lock (_lock) {
+ if (Bases != null) {
+ return; // Already set
+ }
+
+ Bases = bases.MaybeEnumerate().ToArray();
+ if (Bases.Count > 0) {
+ AddMember("__base__", Bases[0], true);
+ }
+
+ AddMember("__bases__", new AstPythonSequence(
+ interpreter?.GetBuiltinType(BuiltinTypeId.Tuple),
+ DeclaringModule,
+ Bases,
+ interpreter?.GetBuiltinType(BuiltinTypeId.TupleIterator)
+ ), true);
+ }
+ }
+
+ internal static IReadOnlyList CalculateMro(IPythonType cls, HashSet recursionProtection = null) {
+ if (cls == null) {
+ return Array.Empty();
+ }
+ if (recursionProtection == null) {
+ recursionProtection = new HashSet();
+ }
+ if (!recursionProtection.Add(cls)) {
+ return Array.Empty();
+ }
+ try {
+ var mergeList = new List> { new List() };
+ var finalMro = new List { cls };
+
+ var bases = (cls as AstPythonClass)?.Bases ??
+ (cls.GetMember(null, "__bases__") as IPythonSequenceType)?.IndexTypes ??
+ Array.Empty();
+
+ foreach (var b in bases) {
+ var b_mro = new List();
+ b_mro.AddRange(CalculateMro(b, recursionProtection));
+ mergeList.Add(b_mro);
+ }
+
+ while (mergeList.Any()) {
+ // Next candidate is the first head that does not appear in
+ // any other tails.
+ var nextInMro = mergeList.FirstOrDefault(mro => {
+ var m = mro.FirstOrDefault();
+ return m != null && !mergeList.Any(m2 => m2.Skip(1).Contains(m));
+ })?.FirstOrDefault();
+
+ if (nextInMro == null) {
+ // MRO is invalid, so return just this class
+ return new IPythonType[] { cls };
+ }
+
+ finalMro.Add(nextInMro);
+
+ // Remove all instances of that class from potentially being returned again
+ foreach (var mro in mergeList) {
+ mro.RemoveAll(ns => ns == nextInMro);
+ }
+
+ // Remove all lists that are now empty.
+ mergeList.RemoveAll(mro => !mro.Any());
+ }
+
+ return finalMro;
+ } finally {
+ recursionProtection.Remove(cls);
+ }
+ }
+
+ private bool Push() => _isProcessing.Value ? false : (_isProcessing.Value = true);
+ private void Pop() => _isProcessing.Value = false;
+ }
+}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonConstant.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonConstant.cs
index 42e8009ee..d7b8b05e8 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonConstant.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonConstant.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.
@@ -20,37 +20,14 @@
using Microsoft.PythonTools.Analysis;
namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonConstant : IPythonConstant, IMemberContainer, ILocatedMember {
- private readonly Dictionary _cachedMembers = new Dictionary();
-
- public AstPythonConstant(IPythonType type, params ILocationInfo[] locations) {
+ class AstPythonConstant : AstPythonTypeWrapper, IPythonConstant {
+ public AstPythonConstant(IPythonType type, params ILocationInfo[] locations): base(type, type.DeclaringModule) {
Type = type ?? throw new ArgumentNullException(nameof(type));
Locations = locations.ToArray();
}
- public IEnumerable Locations { get; }
- public PythonMemberType MemberType => PythonMemberType.Constant;
+ public override IEnumerable Locations { get; }
+ public override PythonMemberType MemberType => PythonMemberType.Constant;
public IPythonType Type { get; }
-
- public IMember GetMember(IModuleContext context, string name) {
- IMember m;
- lock (_cachedMembers) {
- if (_cachedMembers.TryGetValue(name, out m)) {
- return m;
- }
- }
-
- m = Type?.GetMember(context, name);
- if (m is IPythonFunction f && !f.IsStatic) {
- m = new AstPythonBoundMethod(f, Type);
- lock (_cachedMembers) {
- _cachedMembers[name] = m;
- }
- }
- return m;
- }
-
- public IEnumerable GetMemberNames(IModuleContext moduleContext)
- => Type?.GetMemberNames(moduleContext);
}
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonFunction.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonFunction.cs
index f9c210a39..cf79624e2 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonFunction.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonFunction.cs
@@ -9,12 +9,11 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using Microsoft.PythonTools.Analysis;
@@ -22,24 +21,24 @@
using Microsoft.PythonTools.Parsing.Ast;
namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonFunction : IPythonFunction2, ILocatedMember, IHasQualifiedName {
- private readonly List _overloads;
+ class AstPythonFunction : AstPythonType, IPythonFunction {
+ private readonly List _overloads = new List();
private readonly string _doc;
+ private readonly object _lock = new object();
public AstPythonFunction(
- PythonAst ast,
- IPythonModule declModule,
- IPythonType declType,
- FunctionDefinition def,
+ FunctionDefinition fd,
+ IPythonModule declaringModule,
+ IPythonType declaringType,
ILocationInfo loc
- ) {
- DeclaringModule = declModule ?? throw new ArgumentNullException(nameof(declModule));
- DeclaringType = declType;
- FunctionDefinition = def;
+ ) : base(fd.Name, declaringModule, fd.Documentation, loc,
+ declaringType != null ? BuiltinTypeId.Method : BuiltinTypeId.Function, true) {
+
+ FunctionDefinition = fd;
+ DeclaringType = declaringType;
- Name = FunctionDefinition.Name;
if (Name == "__init__") {
- _doc = declType?.Documentation;
+ _doc = declaringType?.Documentation;
}
foreach (var dec in (FunctionDefinition.Decorators?.Decorators).MaybeEnumerate().ExcludeDefault().OfType()) {
@@ -49,33 +48,53 @@ ILocationInfo loc
IsStatic = true;
}
}
-
- _overloads = new List();
-
- Locations = loc != null ? new[] { loc } : Array.Empty();
}
- public FunctionDefinition FunctionDefinition { get; }
+ #region IMember
+ public override PythonMemberType MemberType
+ => TypeId == BuiltinTypeId.Function ? PythonMemberType.Function : PythonMemberType.Method;
+ #endregion
- internal void AddOverload(IPythonFunctionOverload overload) => _overloads.Add(overload);
+ #region IPythonFunction
+ public FunctionDefinition FunctionDefinition { get; }
+ public IPythonType DeclaringType { get; }
+ public override string Documentation => _doc ?? _overloads.FirstOrDefault()?.Documentation;
+ public virtual bool IsClassMethod { get; }
+ public virtual bool IsStatic { get; }
+ public IReadOnlyList Overloads => _overloads.ToArray();
+ #endregion
- public IPythonModule DeclaringModule {get;}
- public IPythonType DeclaringType {get;}
- public string Name { get; }
- public string Documentation => _doc ?? _overloads.FirstOrDefault()?.Documentation;
- public bool IsBuiltin => true;
+ #region IHasQualifiedName
+ public override string FullyQualifiedName => FullyQualifiedNamePair.CombineNames();
+ public override KeyValuePair FullyQualifiedNamePair =>
+ new KeyValuePair((DeclaringType as IHasQualifiedName)?.FullyQualifiedName ?? DeclaringType?.Name ?? DeclaringModule?.Name, Name);
+ #endregion
- public bool IsClassMethod { get; }
- public bool IsStatic { get; }
+ internal virtual void AddOverload(IPythonFunctionOverload overload) {
+ lock (_lock) {
+ _overloads.Add(overload);
+ }
+ }
- public PythonMemberType MemberType => DeclaringType == null ? PythonMemberType.Function : PythonMemberType.Method;
+ internal IPythonFunction ToUnbound() => new AstPythonUnboundMethod(this);
- public IReadOnlyList Overloads => _overloads.ToArray();
+ ///
+ /// Represents unbound method, such in C.f where C is class rather than the instance.
+ ///
+ class AstPythonUnboundMethod : AstPythonTypeWrapper, IPythonFunction {
+ private readonly IPythonFunction _pf;
- public IEnumerable Locations { get; }
+ public AstPythonUnboundMethod(IPythonFunction function) : base(function, function.DeclaringModule) {
+ _pf = function;
+ }
- public string FullyQualifiedName => FullyQualifiedNamePair.CombineNames();
- public KeyValuePair FullyQualifiedNamePair =>
- new KeyValuePair((DeclaringType as IHasQualifiedName)?.FullyQualifiedName ?? DeclaringType?.Name ?? DeclaringModule?.Name, Name);
+ public FunctionDefinition FunctionDefinition => _pf.FunctionDefinition;
+ public IPythonType DeclaringType => _pf.DeclaringType;
+ public bool IsStatic => _pf.IsStatic;
+ public bool IsClassMethod => _pf.IsClassMethod;
+ public IReadOnlyList Overloads => _pf.Overloads;
+ public override BuiltinTypeId TypeId => BuiltinTypeId.Function;
+ public override PythonMemberType MemberType => PythonMemberType.Function;
+ }
}
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonInterpreter.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonInterpreter.cs
index 1fc27c250..ef4ec8ce6 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonInterpreter.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonInterpreter.cs
@@ -31,8 +31,8 @@ namespace Microsoft.PythonTools.Interpreter.Ast {
internal class AstPythonInterpreter : IPythonInterpreter2, IModuleContext {
private readonly ConcurrentDictionary _modules = new ConcurrentDictionary();
private readonly Dictionary _builtinTypes = new Dictionary() {
- { BuiltinTypeId.NoneType, new AstPythonBuiltinType("NoneType", BuiltinTypeId.NoneType) },
- { BuiltinTypeId.Unknown, new AstPythonBuiltinType("Unknown", BuiltinTypeId.Unknown) }
+ { BuiltinTypeId.NoneType, new AstPythonType("NoneType", BuiltinTypeId.NoneType) },
+ { BuiltinTypeId.Unknown, new AstPythonType("Unknown", BuiltinTypeId.Unknown) }
};
private readonly AstPythonInterpreterFactory _factory;
@@ -88,10 +88,10 @@ public IPythonType GetBuiltinType(BuiltinTypeId id) {
if (string.IsNullOrEmpty(name)) {
Debug.Assert(id == BuiltinTypeId.Unknown, $"no name for {id}");
if (!_builtinTypes.TryGetValue(BuiltinTypeId.Unknown, out res)) {
- _builtinTypes[BuiltinTypeId.Unknown] = res = new AstPythonType("");
+ _builtinTypes[BuiltinTypeId.Unknown] = res = new AstPythonType("", bm, null, null, BuiltinTypeId.Unknown);
}
} else {
- res = new AstPythonType(name);
+ res = new AstPythonType(name, bm, null, null, id);
}
}
_builtinTypes[id] = res;
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonIterables.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonIterables.cs
index bdce104d4..331ad60ad 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonIterables.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonIterables.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.
@@ -18,66 +18,29 @@
using System.Linq;
namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonIterable : IPythonIterableType {
- private readonly IPythonType _type;
-
+ class AstPythonIterable : AstPythonTypeWrapper, IPythonIterableType {
public AstPythonIterable(
IPythonType iterableType,
IEnumerable types,
IPythonType iteratorBase,
- IPythonModule declModule
- ) {
- _type = iterableType;
- IteratorType = new AstPythonIterator(iteratorBase, types, declModule);
- DeclaringModule = declModule;
- }
-
- public AstPythonIterable(
- IPythonType iterableType,
- IEnumerable types,
- IPythonIteratorType iteratorType,
- IPythonModule declModule
- ) {
- _type = iterableType;
- IteratorType = iteratorType;
- DeclaringModule = declModule;
+ IPythonModule declaringModule
+ ) : base(iterableType, declaringModule) {
+ IteratorType = new AstPythonIterator(iteratorBase, types, declaringModule);
}
public IPythonIteratorType IteratorType { get; }
- public IPythonModule DeclaringModule { get; }
-
- public string Name => _type.Name;
- public string Documentation => _type.Documentation;
- public BuiltinTypeId TypeId => _type.TypeId;
- public IReadOnlyList Mro => _type.Mro;
- public bool IsBuiltin => _type.IsBuiltin;
- public PythonMemberType MemberType => _type.MemberType;
- public IPythonFunction GetConstructors() => _type.GetConstructors();
- public IMember GetMember(IModuleContext context, string name) => _type.GetMember(context, name);
- public IEnumerable GetMemberNames(IModuleContext moduleContext) => _type.GetMemberNames(moduleContext);
}
- class AstPythonIterator : IPythonIteratorType, IPythonIterableType {
+ class AstPythonIterator : AstPythonTypeWrapper, IPythonIteratorType, IPythonIterableType {
private readonly IPythonType _type;
- public AstPythonIterator(IPythonType iterableType, IEnumerable nextType, IPythonModule declModule) {
+ public AstPythonIterator(IPythonType iterableType, IEnumerable nextType, IPythonModule declaringModule):
+ base(iterableType, declaringModule) {
_type = iterableType;
NextType = nextType.ToArray();
- DeclaringModule = declModule;
}
public IPythonIteratorType IteratorType => this;
public IEnumerable NextType { get; }
- public IPythonModule DeclaringModule { get; }
-
- public string Name => _type.Name;
- public string Documentation => _type.Documentation;
- public BuiltinTypeId TypeId => _type.TypeId;
- public IReadOnlyList Mro => _type.Mro;
- public bool IsBuiltin => _type.IsBuiltin;
- public PythonMemberType MemberType => _type.MemberType;
- public IPythonFunction GetConstructors() => _type.GetConstructors();
- public IMember GetMember(IModuleContext context, string name) => _type.GetMember(context, name);
- public IEnumerable GetMemberNames(IModuleContext moduleContext) => _type.GetMemberNames(moduleContext);
}
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonLookup.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonLookup.cs
index b4e470834..0aae6ccc2 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonLookup.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonLookup.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.
@@ -19,8 +19,7 @@
using System.Linq;
namespace Microsoft.PythonTools.Interpreter.Ast {
- class AstPythonLookup : IPythonLookupType, IPythonIterableType {
- private readonly IPythonType _lookupType;
+ class AstPythonLookup : AstPythonTypeWrapper, IPythonLookupType, IPythonIterableType {
private readonly IReadOnlyDictionary> _mapping;
public AstPythonLookup(
@@ -30,12 +29,10 @@ public AstPythonLookup(
IEnumerable values,
IEnumerable>> mapping,
IPythonIteratorType iterator
- ) {
- _lookupType = lookupType;
+ ): base(lookupType, declaringModule) {
KeyTypes = (keys ?? throw new ArgumentNullException(nameof(keys))).ToArray();
ValueTypes = (values ?? throw new ArgumentNullException(nameof(values))).ToArray();
_mapping = mapping?.ToDictionary(k => k.Key, k => (IReadOnlyList)k.Value.ToArray());
- DeclaringModule = declaringModule;
IteratorType = iterator;
}
@@ -50,16 +47,8 @@ public IEnumerable GetIndex(IPythonType key) {
public IPythonIteratorType IteratorType { get; }
- public IPythonModule DeclaringModule { get; }
-
- public string Name => _lookupType?.Name ?? "tuple";
- public string Documentation => _lookupType?.Documentation ?? string.Empty;
- public BuiltinTypeId TypeId => _lookupType?.TypeId ?? BuiltinTypeId.Tuple;
- public IReadOnlyList Mro => _lookupType?.Mro ?? Array.Empty();
- public bool IsBuiltin => _lookupType?.IsBuiltin ?? true;
- public PythonMemberType MemberType => _lookupType?.MemberType ?? PythonMemberType.Class;
- public IPythonFunction GetConstructors() => _lookupType?.GetConstructors();
- public IMember GetMember(IModuleContext context, string name) => _lookupType?.GetMember(context, name) ?? null;
- public IEnumerable GetMemberNames(IModuleContext moduleContext) => _lookupType?.GetMemberNames(moduleContext) ?? Enumerable.Empty();
+ public override string Name => InnerType?.Name ?? "tuple";
+ public override BuiltinTypeId TypeId => InnerType?.TypeId ?? BuiltinTypeId.Tuple;
+ public override PythonMemberType MemberType => InnerType?.MemberType ?? PythonMemberType.Class;
}
}
diff --git a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs
index 36865cd46..0c4d509d1 100644
--- a/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs
+++ b/src/Analysis/Engine/Impl/Interpreter/Ast/AstPythonModule.cs
@@ -26,21 +26,20 @@
using Microsoft.PythonTools.Parsing.Ast;
namespace Microsoft.PythonTools.Interpreter.Ast {
- sealed class AstPythonModule : IPythonModule, IProjectEntry, ILocatedMember {
+ sealed class AstPythonModule : PythonModuleType, IPythonModule, IProjectEntry, ILocatedMember {
private readonly IPythonInterpreter _interpreter;
private readonly List _childModules = new List();
private readonly Dictionary _members = new Dictionary();
private bool _foundChildModules;
private string _documentation = string.Empty;
- internal AstPythonModule() {
- Name = string.Empty;
- FilePath = string.Empty;
+ internal AstPythonModule(): base(string.Empty) {
+ FilePath = string.Empty;
_foundChildModules = true;
}
- internal AstPythonModule(string moduleName, IPythonInterpreter interpreter, string documentation, string filePath, IEnumerable parseErrors) {
- Name = moduleName;
+ internal AstPythonModule(string moduleName, IPythonInterpreter interpreter, string documentation, string filePath, IEnumerable parseErrors):
+ base(moduleName) {
_documentation = documentation;
FilePath = filePath;
DocumentUri = ProjectEntry.MakeDocumentUri(FilePath);
@@ -65,8 +64,7 @@ internal void Analyze(PythonAst ast, PathResolverSnapshot currentPathResolver) {
public void Dispose() { }
- public string Name { get; }
- public string Documentation {
+ public override string Documentation {
get {
if (_documentation == null) {
_members.TryGetValue("__doc__", out var m);
@@ -84,7 +82,6 @@ public string Documentation {
}
public string FilePath { get; }
public Uri DocumentUri { get; }
- public PythonMemberType MemberType => PythonMemberType.Module;
public Dictionary