IAnalysisSet IAnalysisSet.Union(IEnumerable <AnalysisValue> items, out bool wasChanged, bool canMutate) { if (items.All(av => ((IAnalysisSet)this).Comparer.Equals(this, av))) { wasChanged = false; return(this); } wasChanged = true; return(AnalysisSet.Create(items).Add(this, false)); }
public void SetOfTwo_Object() { var set = AnalysisSet.Create(new[] { nsA1, nsA2 }); Assert.IsInstanceOfType(set, typeof(AnalysisSetTwoObject)); AssertUtil.ContainsExactly(set, nsA1, nsA2); set = AnalysisSet.Create(new[] { nsA1, nsA1, nsA2, nsA2 }); Assert.IsInstanceOfType(set, typeof(AnalysisSetTwoObject)); AssertUtil.ContainsExactly(set, nsA1, nsA2); }
public override IAnalysisSet Call(Node node, AnalysisUnit unit, IAnalysisSet[] args, NameExpression[] keywordArgNames) { var returnTypes = GetFunctionOverloads().Where(o => o.ReturnType != null).SelectMany(o => o.ReturnType); var types = returnTypes.Select(t => { var av = ProjectState.GetAnalysisValueFromObjects(t); return(t.IsTypeFactory ? AnalysisSet.Create(av) : ProjectState.GetAnalysisValueFromObjects(t).GetInstanceType()); }); return(AnalysisSet.UnionAll(types)); }
public void ManySet_Object() { var set = AnalysisSet.Create(new[] { nsA1, nsA2, nsB1, nsB2 }); Assert.IsInstanceOfType(set, typeof(AnalysisHashSet)); Assert.AreEqual(4, set.Count); AssertUtil.ContainsExactly(set, nsA1, nsA2, nsB1, nsB2); set = AnalysisSet.Create(new[] { nsA1, nsA1, nsA2, nsA2, nsB1, nsB1, nsB2, nsB2 }); Assert.IsInstanceOfType(set, typeof(AnalysisHashSet)); Assert.AreEqual(4, set.Count); AssertUtil.ContainsExactly(set, nsA1, nsA2, nsB1, nsB2); }
private static void MergeTypes(Dictionary <string, IAnalysisSet> res, string key, IEnumerable <AnalysisValue> types) { IAnalysisSet set; if (!res.TryGetValue(key, out set)) { res[key] = set = AnalysisSet.Create(types); } else { res[key] = set.Union(types); } }
public void SetOfOne_Object() { var set = AnalysisSet.Create(nsA1); Assert.AreSame(nsA1, set); set = AnalysisSet.Create(new[] { nsA1 }.AsEnumerable()); Assert.AreSame(nsA1, set); set = AnalysisSet.Create(new[] { nsA1, nsA1 }.AsEnumerable()); Assert.AreSame(nsA1, set); set = AnalysisSet.Create(new[] { nsA1, nsA2 }.AsEnumerable()); Assert.AreNotSame(nsA1, set); }
public IAnalysisSet Union(IEnumerable <AnalysisProxy> items, out bool wasChanged) { if (items == null || items is AnalysisSetEmptyObject || items is AnalysisSetEmptyUnion) { wasChanged = false; return(this); } if (items is AnalysisProxy || items is AnalysisSetTwoObject) { wasChanged = true; return((IAnalysisSet)items); } wasChanged = items.Any(); return(wasChanged ? AnalysisSet.Create(items) : this); }
/// <summary> /// Copies all of our key types into the provided VariableDef. /// </summary> internal bool CopyKeysTo(VariableDef to) { bool added = false; foreach (var dependency in _dependencies) { added |= to.AddTypes(dependency.Key, AnalysisSet.Create(dependency.Value.KeyValues.Keys)); } if (added) { EnqueueDependents(); } return(added); }
/// <summary> /// Gets information about the available signatures for the given expression. /// </summary> /// <param name="exprText">The expression to get signatures for.</param> /// <param name="location">The location in the file.</param> /// <remarks>New in 2.2</remarks> public IEnumerable <IOverloadResult> GetSignatures(string exprText, SourceLocation location) { try { var scope = FindScope(location); var unit = GetNearestEnclosingAnalysisUnit(scope); var eval = new ExpressionEvaluator(unit.CopyForEval(), scope, mergeScopes: true); using (var parser = Parser.CreateParser(new StringReader(exprText), _unit.ProjectState.LanguageVersion)) { var expr = GetExpression(parser.ParseTopExpression().Body); if (expr is ListExpression || expr is TupleExpression || expr is DictionaryExpression) { return(Enumerable.Empty <IOverloadResult>()); } var lookup = eval.Evaluate(expr); lookup = AnalysisSet.Create(lookup.Where(av => !(av is MultipleMemberInfo)).Concat( lookup.OfType <MultipleMemberInfo>().SelectMany(mmi => mmi.Members) )); var result = new HashSet <OverloadResult>(OverloadResultComparer.Instance); // TODO: Include relevant type info on the parameter... result.UnionWith(lookup // Exclude constant values first time through .Where(av => av.MemberType != PythonMemberType.Constant) .SelectMany(av => av.Overloads ?? Enumerable.Empty <OverloadResult>()) ); if (!result.Any()) { result.UnionWith(lookup .Where(av => av.MemberType == PythonMemberType.Constant) .SelectMany(av => av.Overloads ?? Enumerable.Empty <OverloadResult>())); } return(result); } } catch (Exception ex) { if (ex.IsCriticalException()) { throw; } Debug.Fail(ex.ToString()); return(GetSignaturesError); } }
public bool AddTypes(ProjectEntry projectEntry, JsAnalyzer projectState, IAnalysisSet keyTypes, IAnalysisSet valueTypes, bool enqueue = true) { bool anyAdded = false; if (keyTypes.Count > 0) { var dependencies = GetDependentItems(projectEntry); if (dependencies.KeyValues.Count > projectState.Limits.DictKeyTypes) { dependencies.MakeUnionStronger(); } foreach (var key in keyTypes) { IAnalysisSet values; if (!dependencies.KeyValues.TryGetValue(key, out values)) { values = AnalysisSet.Create(valueTypes); anyAdded = true; } else { bool added; values = values.Union(valueTypes, out added); anyAdded |= added; } if (anyAdded && values.Count > projectState.Limits.DictValueTypes) { values = values.AsStrongerUnion(); } dependencies.KeyValues[key] = values; } #if FALSE // Currently unused but could come back if (anyAdded) { _allValues = null; } #endif if (anyAdded && enqueue) { EnqueueDependents(); } } return(anyAdded); }
public void EmptySet_Add_Object() { var set = AnalysisSet.Empty; set.Should().BeOfType <AnalysisSetEmptyObject>(); set = AnalysisSet.Create(); set.Should().BeOfType <AnalysisSetEmptyObject>().And.BeSameAs(AnalysisSet.Empty); set = set.Add(nsA1, out var added, false); added.Should().BeTrue(); set.Should().BeSameAs(nsA1); set = AnalysisSet.Empty; set = set.Add(nsA1, out added, true); added.Should().BeTrue(); set.Should().BeSameAs(nsA1); }
public override IAnalysisSet GetIndex(Node node, AnalysisUnit unit, IAnalysisSet index) { // TODO: Needs to actually do indexing on type var clrType = _type as IAdvancedPythonType; if (clrType == null || !clrType.IsGenericTypeDefinition) { return(AnalysisSet.Empty); } var result = AnalysisSet.Create(); foreach (var indexType in index) { if (indexType is BuiltinClassInfo) { var clrIndexType = indexType.PythonType; try { var klass = ProjectState.MakeGenericType(clrType, clrIndexType); result = result.Add(klass); } catch { // wrong number of type args, violated constraint, etc... } } else if (indexType is SequenceInfo) { List <IPythonType>[] types = GetSequenceTypes(indexType as SequenceInfo); if (!MissingType(types)) { foreach (IPythonType[] indexTypes in GetTypeCombinations(types)) { try { var klass = ProjectState.MakeGenericType(clrType, indexTypes); result = result.Add(klass); } catch { // wrong number of type args, violated constraint, etc... } } } } } return(result); }
public bool AddTypes(IProjectEntry projectEntry, PythonAnalyzer projectState, IEnumerable <AnalysisValue> keyTypes, IEnumerable <AnalysisValue> valueTypes, bool enqueue = true) { var dependencies = GetDependentItems(projectEntry); if (dependencies.KeyValues.Count > projectState.Limits.DictKeyTypes) { dependencies.MakeUnionStronger(); } bool anyAdded = false; foreach (var key in keyTypes) { IAnalysisSet values; if (!dependencies.KeyValues.TryGetValue(key, out values)) { values = AnalysisSet.Create(valueTypes); anyAdded = true; } else { bool added; values = values.Union(valueTypes, out added); anyAdded |= added; } if (anyAdded && values.Count > projectState.Limits.DictValueTypes) { values = values.AsStrongerUnion(); } dependencies.KeyValues[key] = values; } if (anyAdded) { _allValues = null; } if (anyAdded && enqueue) { EnqueueDependents(); } return(anyAdded); }
public void EmptySet_Add_Object() { var set = AnalysisSet.Empty; Assert.IsInstanceOfType(set, typeof(AnalysisSetEmptyObject)); set = AnalysisSet.Create(); Assert.IsInstanceOfType(set, typeof(AnalysisSetEmptyObject)); Assert.AreSame(AnalysisSet.Empty, set); bool added; set = set.Add(nsA1, out added, false); Assert.IsTrue(added); Assert.AreSame(nsA1, set); set = AnalysisSet.Empty; set = set.Add(nsA1, out added, true); Assert.IsTrue(added); Assert.AreSame(nsA1, set); }
private void LoadKnownTypes() { _itemCache.Clear(); ModuleReference moduleRef; if (Modules.TryImport(_builtinName, out moduleRef)) { _builtinModule = (BuiltinModule)moduleRef.Module; } else { var fallbackDb = PythonTypeDatabase.CreateDefaultTypeDatabase(LanguageVersion.ToVersion()); _builtinModule = _modules.GetBuiltinModule(fallbackDb.GetModule(SharedDatabaseState.BuiltinName2x)); Modules[_builtinName] = new ModuleReference(_builtinModule); } Types = new KnownTypes(this); ClassInfos = (IKnownClasses)Types; _noneInst = (ConstantInfo)GetCached(_nullKey, () => new ConstantInfo(ClassInfos[BuiltinTypeId.NoneType], (object)null)); DoNotUnionInMro = AnalysisSet.Create(new AnalysisValue[] { ClassInfos[BuiltinTypeId.Object], ClassInfos[BuiltinTypeId.Type] }); AddBuiltInSpecializations(); ModuleReference sysModule; if (_modules.TryImport("sys", out sysModule)) { var bm = sysModule.AnalysisModule as BuiltinModule; if (bm != null) { sysModule.Module = new SysModuleInfo(bm); } } }
public void SetOfOne_Add_Object() { var set = AnalysisSet.Create(nsA1); set = set.Add(nsA1, out var added, true); added.Should().BeFalse(); set.Should().BeSameAs(nsA1); set = set.Add(nsA1, out added, false); added.Should().BeFalse(); set.Should().BeSameAs(nsA1); set = set.Add(nsB1, out added, true); added.Should().BeTrue(); set.Should().BeOfType <AnalysisSetTwoObject>(); set = AnalysisSet.Create(nsA1); var set2 = set.Add(nsA1, out added, true); added.Should().BeFalse(); set2.Should().BeSameAs(set).And.OnlyContain(nsA1); }
private async Task LoadKnownTypesAsync() { _itemCache.Clear(); var fallback = new FallbackBuiltinModule(_langVersion); var moduleRef = await Modules.TryImportAsync(_builtinName).ConfigureAwait(false); if (moduleRef != null) { _builtinModule = (BuiltinModule)moduleRef.Module; } else { _builtinModule = new BuiltinModule(fallback, this); Modules[_builtinName] = new ModuleReference(_builtinModule, _builtinName); } Modules.AddBuiltinModuleWrapper("sys", SysModuleInfo.Wrap); Modules.AddBuiltinModuleWrapper("typing", TypingModuleInfo.Wrap); Types = KnownTypes.Create(this, fallback); ClassInfos = (IKnownClasses)Types; _noneInst = (ConstantInfo)GetCached( _nullKey, () => new ConstantInfo(ClassInfos[BuiltinTypeId.NoneType], null, PythonMemberType.Constant) ); DoNotUnionInMro = AnalysisSet.Create(new AnalysisValue[] { ClassInfos[BuiltinTypeId.Object], ClassInfos[BuiltinTypeId.Type] }); AddBuiltInSpecializations(); }
private void FinishLoadKnownTypes(PythonTypeDatabase db) { _itemCache.Clear(); if (db == null) { db = PythonTypeDatabase.CreateDefaultTypeDatabase(LanguageVersion.ToVersion()); Types = KnownTypes.Create(this, db); } else { Types = KnownTypes.CreateDefault(this, db); } ClassInfos = (IKnownClasses)Types; _noneInst = (ConstantInfo)GetCached(_nullKey, () => new ConstantInfo(ClassInfos[BuiltinTypeId.NoneType], (object)null)); DoNotUnionInMro = AnalysisSet.Create(new AnalysisValue[] { ClassInfos[BuiltinTypeId.Object], ClassInfos[BuiltinTypeId.Type] }); AddBuiltInSpecializations(); }
internal void AssignTo(Node assignStmt, Expression left, IAnalysisSet values) { if (left is ExpressionWithAnnotation) { left = ((ExpressionWithAnnotation)left).Expression; // "x:t=..." is a recommended pattern - we do not want to // actually assign the ellipsis in this case. if (values.Any(v => v.TypeId == BuiltinTypeId.Ellipsis)) { values = AnalysisSet.Create(values.Where(v => v.TypeId != BuiltinTypeId.Ellipsis), values.Comparer); } } if (left is NameExpression) { var l = (NameExpression)left; if (!string.IsNullOrEmpty(l.Name)) { Scope.AssignVariable( l.Name, l, _unit, values ); } } else if (left is MemberExpression) { var l = (MemberExpression)left; if (!string.IsNullOrEmpty(l.Name)) { foreach (var obj in Evaluate(l.Target).Resolve(_unit)) { obj.SetMember(l, _unit, l.Name, values.Resolve(_unit)); } } } else if (left is IndexExpression) { var l = (IndexExpression)left; var indexObj = Evaluate(l.Index); foreach (var obj in Evaluate(l.Target).Resolve(_unit)) { obj.SetIndex(assignStmt, _unit, indexObj, values.Resolve(_unit)); } } else if (left is SequenceExpression) { // list/tuple var l = (SequenceExpression)left; var valuesArr = values.ToArray(); for (var i = 0; i < l.Items.Count; i++) { if (valuesArr.Length > 0) { foreach (var value in valuesArr) { AssignTo(assignStmt, l.Items[i], value.GetIndex(assignStmt, _unit, ProjectState.GetConstant(i))); } } else { AssignTo(assignStmt, l.Items[i], AnalysisSet.Empty); } } } }
/// <summary> /// Gets instance representations of all members of the set. /// </summary> public static IAnalysisSet GetInstanceType(this IAnalysisSet types) => AnalysisSet.Create(types.SelectMany(ns => ns.PythonType?.IsTypeFactory == true ? ns : ns.GetInstanceType()));
public T GetValue <T>(IPythonProjectEntry module, string variable, int index = 0) where T : AnalysisValue { var rs = module.Analysis.GetValuesByIndex(variable, index).ToArray(); if (rs.Length == 0) { Assert.Fail("'{0}.{1}' had no variables".FormatInvariant(module.ModuleName, variable)); } else if (rs.Length > 1) { foreach (var r in rs) { Trace.TraceInformation(r.ToString()); } Assert.Fail("'{0}.{1}' had multiple values: {2}".FormatInvariant(module.ModuleName, variable, AnalysisSet.Create(rs))); } else { Assert.IsInstanceOfType(rs[0], typeof(T), "'{0}.{1}' was not expected type".FormatInvariant(module.ModuleName, variable)); return((T)rs[0]); } return(default(T)); }
/// <summary> /// Gets instance representations of all members of the set. /// </summary> public static IAnalysisSet GetInstanceType(this IAnalysisSet types) { return(AnalysisSet.Create(types.SelectMany(ns => ns.GetInstanceType()))); }