public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name) { // Must unconditionally call the base implementation of GetMember var ignored = base.GetMember(node, unit, name); var mro = ClassInfo._mro; if (!mro.IsValid) { return(AnalysisSet.Empty); } // First item in MRO list is always the class itself. var member = Values.Mro.GetMemberFromMroNoReferences(mro.Skip(1), node, unit, name, addRef: true); if (member == null) { return(AnalysisSet.Empty); } var instances = _instances.Any() ? _instances : unit.ProjectState._noneInst.SelfSet; IAnalysisSet result = AnalysisSet.Empty; foreach (var instance in instances) { var desc = member.GetDescriptor(node, instance, this, unit); result = result.Union(desc); } return(result); }
internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { if (strength > 0 && av is ProtocolInfo pi && pi.Push()) { try { var name = _protocols.OfType <NameProtocol>().FirstOrDefault(); if (_protocols.Count == 1 && name != null) { return(this); } var protocols = _protocols.Union(pi._protocols, out bool changed); if (!changed) { return(this); } if (name != null) { protocols.Split <NameProtocol>(out _, out protocols); protocols = protocols.Add(name); } return(new ProtocolInfo(DeclaringModule, State) { _protocols = protocols }); } finally { pi.Pop(); } } return(this); }
private static IAnalysisSet QuickOp(IAnalysisSet lhs, PythonOperator op, IAnalysisSet rhs, PythonAnalyzer state) { // Concrete return for known (or conventional) operations switch (op) { case PythonOperator.Equal: case PythonOperator.In: case PythonOperator.Is: case PythonOperator.IsNot: case PythonOperator.Not: case PythonOperator.NotEqual: case PythonOperator.NotIn: return(state.ClassInfos[BuiltinTypeId.Bool].Instance); case PythonOperator.GreaterThan: case PythonOperator.GreaterThanOrEqual: case PythonOperator.LessThan: case PythonOperator.LessThanOrEqual: return(lhs.Union(rhs)); case PythonOperator.Negate: case PythonOperator.Pos: return(rhs); } return(null); }
private static IAnalysisSet FsBasename(FunctionValue func, Node node, AnalysisUnit unit, IAnalysisSet @this, IAnalysisSet[] args) { CallNode call = (CallNode)node; IAnalysisSet res = AnalysisSet.Empty; if (args.Length == 2) { foreach (var extArg in args[1]) { var strExt = extArg.Value.GetStringValue(); if (strExt != null) { foreach (var nameArg in args[0]) { string name = nameArg.Value.GetStringValue(); if (name != null) { string oldName = name; if (name.EndsWith(strExt, StringComparison.OrdinalIgnoreCase)) { name = name.Substring(0, name.Length - strExt.Length); } res = res.Union(unit.Analyzer.GetConstant(name).Proxy); } } } } } if (res.Count == 0) { return(unit.Analyzer._emptyStringValue.SelfSet); } return(res); }
public IAnalysisSet GetValue(Node node, AnalysisUnit unit, ProjectEntry declaringScope, IAnalysisSet @this, bool addRef) { IAnalysisSet res = _propDesc.GetValue(node, unit, declaringScope, @this, addRef); var types = _instance._linkedValues.GetTypes(unit, declaringScope); try { foreach (var prototype in types) { if (ObjectValue.PushProtoLookup(prototype.Value)) { var value = prototype.Value.GetProperty(node, unit, _name); if (value != null) { res = res.Union(value.GetValue(node, unit, declaringScope, @this, addRef)); } } } } finally { foreach (var prototype in types) { ObjectValue.PopProtoLookup(prototype.Value); } } return(res); }
public IAnalysisSet ResolveParameter(AnalysisUnit unit, string name, ArgumentSet arguments) { var parameters = FunctionDefinition.Parameters; if (parameters == null || parameters.Count == 0) { return(ResolveParameter(unit, name)); } for (int i = 0; i < parameters.Count; ++i) { if (parameters[i].Name == name) { IAnalysisSet res = AnalysisSet.Empty; if (i < arguments.Count) { arguments.Args[i].Split(v => (v as ParameterInfo)?.Function != this, out var args, out _); res = res.Union(args); } if (parameters[i].IsList) { arguments.SequenceArgs.Split(v => (v as ParameterInfo)?.Function != this, out var args, out _); res = res.Add(new LazyIndexableInfo(parameters[i], args, () => ResolveParameter(_analysisUnit, parameters[i].Name))); } if (parameters[i].IsDictionary) { arguments.DictArgs.Split(v => (v as ParameterInfo)?.Function != this, out var args, out _); res = res.Add(new LazyIndexableInfo(parameters[i], args, () => ResolveParameter(_analysisUnit, parameters[i].Name))); } return(res); } } return(ResolveParameter(unit, name)); }
private IAnalysisSet GetRecurse(AnalysisValue protoStart, Node node, AnalysisUnit unit, string name, bool addRef) { var prototypes = protoStart.GetPrototype(unit.ProjectEntry); IAnalysisSet protovalue = AnalysisSet.Empty; if (prototypes != null) { try { foreach (var proto in prototypes) { if (PushProtoLookup(proto.Value)) { var property = proto.Value.GetProperty(node, unit, name); if (property != null) { var value = property.GetValue( node, unit, proto.Value.DeclaringModule, this.SelfSet, addRef ); protovalue = protovalue.Union(value); if (property.IsEphemeral) { protovalue = protovalue.Union(GetRecurse(proto.Value, node, unit, name, addRef)); } } else { // keep searching the prototype chain... protovalue = protovalue.Union(GetRecurse(proto.Value, node, unit, name, addRef)); } } } } finally { foreach (var proto in prototypes) { PopProtoLookup(proto.Value); } } } return(protovalue); }
internal override AnalysisValue UnionMergeTypes(AnalysisValue av, int strength) { var combined = _indexTypes.Union(((av as LazyIndexableInfo)?._indexTypes).MaybeEnumerate().Where(v => !ReferenceEquals(v, this))); if (!combined.SetEquals(_indexTypes)) { return(new LazyIndexableInfo(Node, combined, _fallback)); } return(this); }
private IAnalysisSet ChooseBest(IAnalysisSet x, IAnalysisSet y) { if (x == null || x.IsObjectOrUnknown()) { return((y == null || y.IsObjectOrUnknown()) ? AnalysisSet.Empty : y); } if (y == null || y.IsObjectOrUnknown()) { return(AnalysisSet.Empty); } return(x.Union(y)); }
private static void TestImmutableSet(IAnalysisSet emptySet) { int count = emptySet.Count; var projectEntry = CreateProjectEntry(); var value = new TestAnalysisValue(projectEntry); var newSet = emptySet.Add(value.Proxy); Assert.AreNotEqual(emptySet, newSet); Assert.AreEqual(count, emptySet.Count); Assert.AreEqual(count + 1, newSet.Count); bool wasChanged; newSet = emptySet.Add(value.Proxy, out wasChanged); Assert.AreNotEqual(emptySet, newSet); Assert.IsTrue(wasChanged); Assert.AreEqual(count, emptySet.Count); Assert.AreEqual(count + 1, newSet.Count); newSet = emptySet.Union(new[] { value.Proxy }); Assert.AreNotEqual(emptySet, newSet); Assert.AreEqual(count, emptySet.Count); Assert.AreEqual(count + 1, newSet.Count); newSet = emptySet.Union(new[] { value.Proxy }, out wasChanged); Assert.IsTrue(wasChanged); Assert.AreNotEqual(emptySet, newSet); Assert.AreEqual(count, emptySet.Count); Assert.AreEqual(count + 1, newSet.Count); Assert.AreEqual(emptySet, emptySet.Clone()); Assert.IsFalse(emptySet.Contains(value.Proxy)); }
/// <summary> /// Merges all the types in <paramref name="sets" /> into this set. /// </summary> /// <param name="sets">The sets to merge into this set.</param> /// <param name="wasChanged">Returns True if the contents of the /// returned set are different to the original set.</param> public static IAnalysisSet UnionAll(this IAnalysisSet set, IEnumerable <IAnalysisSet> sets, out bool wasChanged) { bool changed; wasChanged = false; foreach (var s in sets) { var newSet = set.Union(s, out changed); if (changed) { wasChanged = true; } set = newSet; } return(set); }
internal static IAnalysisSet Resolve(this IAnalysisSet self, AnalysisUnit unit, ResolutionContext context, out bool changed) { // The vast majority of the time, no values are resolved // So we want to quickly validate and get out without allocating // or changing anything. if (!context.Push()) { changed = false; return(self); } try { List <AnalysisValue> removed = null; IAnalysisSet added = null; foreach (var ns in self) { var r = ns.Resolve(unit, context); if (!ReferenceEquals(r, ns)) { if (removed == null) { removed = new List <AnalysisValue>(self.Count); } removed.Add(ns); added = added?.Union(r) ?? r; } } if (removed == null) { changed = false; return(self); } self.Split(removed.Contains, out _, out var unchanged); var res = unchanged.Union(added, out changed); if (changed && res.SetEquals(self)) { changed = false; return(self); } return(res); } finally { context.Pop(); } }
private bool TryInvokeMethod(Node node, AnalysisUnit unit, string name, IAnalysisSet[] args, out IAnalysisSet res) { res = AnalysisSet.Empty; bool invoked = false; var members = GetTypeMember(node, unit, name); foreach (var member in members) { if (ShouldInvokeMethod(member, name)) { invoked = true; res = res.Union( member.Call( node, unit, args, ExpressionEvaluator.EmptyNames ) ); } } return invoked; }
protected override void EnsureUnionType() { if (_unionType == null) { IAnalysisSet unionType = AnalysisSet.EmptyUnion; if (Push()) { try { foreach (var set in _indexTypes) { unionType = unionType.Union(set.TypesNoCopy); } } finally { Pop(); } } _unionType = unionType; } }
private void RecomputeBaseSpecialization() { IAnalysisSet builtinClassSet = AnalysisSet.Empty; foreach (var classInfo in _mro) { BuiltinClassInfo builtin = classInfo as BuiltinClassInfo; if (builtin != null && builtin.TypeId != BuiltinTypeId.Object) { var builtinType = _projectState.GetBuiltinType(builtin.PythonType); if (builtinType.GetType() != typeof(BuiltinClassInfo)) { // we have a specialized built-in class, we want its behavior too... builtinClassSet = builtinClassSet.Union(builtinType.SelfSet, true); } } } _baseSpecialization = builtinClassSet; }
protected override void EnsureUnionType() { if (_unionType.IsObjectOrUnknown()) { IAnalysisSet unionType = AnalysisSet.EmptyUnion; if (Push()) { try { foreach (var set in IndexTypes) { unionType = unionType.Union(set.TypesNoCopy); } } finally { Pop(); } } unionType.Split(this.Equals, out _, out unionType); _unionType = unionType; } }
public IAnalysisSet GetValue(Node node, AnalysisUnit unit, ProjectEntry declaringScope, IAnalysisSet @this, bool addRef) { IAnalysisSet res = AnalysisSet.Empty; foreach (var prototype in _instance._prototypes) { if (prototype.Value.Push()) { try { var value = prototype.Value.GetProperty(node, unit, _name); if (value != null) { res = res.Union(value.GetValue(node, unit, declaringScope, @this, addRef)); } } finally { prototype.Value.Pop(); } } } return(res); }
public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name) { var members = base.GetMember(node, unit, name); IAnalysisSet res = AnalysisSet.Empty; bool found = false; foreach (var member in members) { if (ShouldInvokeMethod(member, name)) { found = true; res = res.Union(member.SelfSet); } } if (found) { return(res); } return(_instances.GetMember(node, unit, name)); }
private bool TryInvokeMethod(Node node, AnalysisUnit unit, string name, IAnalysisSet[] args, out IAnalysisSet res) { res = AnalysisSet.Empty; bool invoked = false; var members = GetTypeMember(node, unit, name); foreach (var member in members) { if (ShouldInvokeMethod(member, name)) { invoked = true; res = res.Union( member.Call( node, unit, args, ExpressionEvaluator.EmptyNames ) ); } } return(invoked); }
public static IAnalysisSet Union(this IAnalysisSet set, IEnumerable <AnalysisProxy> items) { bool dummy; return(set.Union(items, out dummy)); }
public void AddPrototypes(IAnalysisSet values) { _prototypes = _prototypes.Union(values); }
public override IAnalysisSet GetMember(Node node, AnalysisUnit unit, string name) { // __getattribute__ takes precedence over everything. IAnalysisSet getattrRes = AnalysisSet.Empty; var getAttribute = _classInfo.GetMemberNoReferences(node, unit.CopyForEval(), "__getattribute__"); if (getAttribute.Count > 0) { foreach (var getAttrFunc in getAttribute) { var func = getAttrFunc as BuiltinMethodInfo; if (func != null && func.Function.DeclaringType.TypeId == BuiltinTypeId.Object) { continue; } // TODO: We should really do a get descriptor / call here getattrRes = getattrRes.Union(getAttrFunc.Call(node, unit, new[] { SelfSet, ProjectState.ClassInfos[BuiltinTypeId.Str].Instance.SelfSet }, ExpressionEvaluator.EmptyNames)); } } // ok, it must be an instance member, or it will become one later VariableDef def; if (_instanceAttrs == null) { _instanceAttrs = new Dictionary <string, VariableDef>(); } if (!_instanceAttrs.TryGetValue(name, out def)) { _instanceAttrs[name] = def = new EphemeralVariableDef(); } def.AddReference(node, unit); def.AddDependency(unit); // now check class members var res = GetTypeMember(node, unit, name); res = res.Union(def.Types); // check and see if it's defined in a base class instance as well... foreach (var b in _classInfo.Bases) { foreach (var ns in b) { if (ns.Push()) { try { ClassInfo baseClass = ns as ClassInfo; if (baseClass != null && baseClass.Instance._instanceAttrs != null && baseClass.Instance._instanceAttrs.TryGetValue(name, out def)) { res = res.Union(def.GetTypesNoCopy(unit, DeclaringModule)); } } finally { ns.Pop(); } } } } if (res.Count == 0) { // and if that doesn't exist fall back to __getattr__ var getAttr = _classInfo.GetMemberNoReferences(node, unit, "__getattr__"); if (getAttr.Count > 0) { foreach (var getAttrFunc in getAttr) { getattrRes = getattrRes.Union(getAttr.Call(node, unit, new[] { SelfSet, _classInfo.AnalysisUnit.State.ClassInfos[BuiltinTypeId.Str].Instance.SelfSet }, ExpressionEvaluator.EmptyNames)); } } return(getattrRes); } return(res); }
private static bool IsSpecialRequire(AnalysisUnit unit, CallNode n, ref IAnalysisSet res) { bool hitLiteral = false; if (n.Arguments.Length == 1) { var ee = new ExpressionEvaluator(unit); foreach (var name in ee.MergeStringLiterals(n.Arguments[0])) { hitLiteral = true; res = res.Union( unit.Analyzer.Modules.RequireModule( n, unit, name, unit.DeclaringModuleEnvironment.Name ) ); } } return hitLiteral; }