This repository was archived by the owner on Nov 4, 2024. It is now read-only.
forked from microsoft/python-language-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBuiltinNamespace.cs
More file actions
116 lines (99 loc) · 4.61 KB
/
BuiltinNamespace.cs
File metadata and controls
116 lines (99 loc) · 4.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// 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 Microsoft.PythonTools.Analysis.Infrastructure;
using Microsoft.PythonTools.Interpreter;
using Microsoft.PythonTools.Parsing.Ast;
namespace Microsoft.PythonTools.Analysis.Values {
/// <summary>
/// Base class for things which get their members primarily via a built-in .NET type.
/// </summary>
class BuiltinNamespace<TMemberContainer> : AnalysisValue where TMemberContainer : IPythonType {
internal Dictionary<string, IAnalysisSet> _specializedValues;
public BuiltinNamespace(TMemberContainer pythonType, PythonAnalyzer projectState) {
ProjectState = projectState ?? throw new ArgumentNullException(nameof(projectState));
Type = pythonType;
// Ideally we'd assert here whenever pythonType is null, but that
// makes debug builds unusable because it happens so often.
}
public override BuiltinTypeId TypeId => Type?.TypeId ?? BuiltinTypeId.Unknown;
public override PythonMemberType MemberType => Type?.MemberType ?? PythonMemberType.Unknown;
public override IAnalysisSet GetTypeMember(Node node, AnalysisUnit unit, string name) {
var res = AnalysisSet.Empty;
if (_specializedValues != null && _specializedValues.TryGetValue(name, out var specializedRes)) {
return specializedRes;
}
if (Type == null) {
return unit.State.ClassInfos[BuiltinTypeId.NoneType].Instance;
}
var member = Type.GetMember(unit.DeclaringModule.InterpreterContext, name);
if (member != null) {
res = ProjectState.GetAnalysisValueFromObjects(member);
}
return res;
}
public override IDictionary<string, IAnalysisSet> GetAllMembers(IModuleContext moduleContext, GetMemberOptions options = GetMemberOptions.None) {
if (Type == null) {
return new Dictionary<string, IAnalysisSet>();
}
return ProjectState.GetAllMembers(Type, moduleContext);
}
public IAnalysisSet this[string name] {
get {
if (TryGetMember(name, out var value)) {
return value;
}
throw new KeyNotFoundException("Key {0} not found".FormatInvariant(name));
}
set {
if (_specializedValues == null) {
_specializedValues = new Dictionary<string, IAnalysisSet>();
}
_specializedValues[name] = value;
}
}
public bool TryGetMember(string name, out IAnalysisSet value) {
if (_specializedValues != null && _specializedValues.TryGetValue(name, out var res)) {
value = res;
return true;
}
if (Type == null) {
value = null;
return false;
}
var member = Type.GetMember(ProjectState._defaultContext, name);
if (member != null) {
value = ProjectState.GetAnalysisValueFromObjects(member);
return true;
}
value = null;
return false;
}
public PythonAnalyzer ProjectState { get; }
public TMemberContainer Type { get; }
public virtual ILocatedMember GetLocatedMember() => null;
public override IEnumerable<ILocationInfo> Locations => GetLocatedMember()?.Locations ?? Enumerable.Empty<ILocationInfo>();
public override bool Equals(object obj) {
if (obj is BuiltinNamespace<TMemberContainer> bn && GetType() == bn.GetType()) {
return Type != null ? Type.Equals(bn.Type) : bn.Type == null;
}
return false;
}
public override int GetHashCode() => new { hc1 = GetType().GetHashCode(), hc2 = Type?.GetHashCode() }.GetHashCode();
}
}