public CPythonFunction(ITypeDatabaseReader typeDb, string name, Dictionary<string, object> functionTable, IMemberContainer declaringType, bool isMethod = false) { _name = name; object doc; if (functionTable.TryGetValue("doc", out doc)) { _doc = doc as string; } object value; if (functionTable.TryGetValue("builtin", out value)) { _isBuiltin = Convert.ToBoolean(value); } else { _isBuiltin = true; } if (functionTable.TryGetValue("static", out value)) { _isStatic = Convert.ToBoolean(value); } else { _isStatic = true; } _hasLocation = false;//PythonTypeDatabase.TryGetLocation(functionTable, ref _line, ref _column); _declaringModule = CPythonModule.GetDeclaringModuleFromContainer(declaringType); _declaringType = declaringType as IPythonType; if (functionTable.TryGetValue("overloads", out value)) { _overloads = LoadOverloads(typeDb, value, isMethod); } }
public IronPythonConstructorFunction(IronPythonInterpreter interpreter, ObjectIdentityHandle[] infos, IPythonType type) { _interpreter = interpreter; _interpreter.UnloadingDomain += Interpreter_UnloadingDomain; _remote = _interpreter.Remote; _infos = infos; _type = type; }
public AstPythonParameterInfo(PythonAst ast, Parameter p) { Name = p.Name; Documentation = ""; DefaultValue = p.DefaultValue?.ToCodeString(ast) ?? ""; IsParamArray = p.Kind == ParameterKind.List; IsKeywordDict = p.Kind == ParameterKind.Dictionary; ParameterTypes = new IPythonType[0]; }
internal CPythonFunction(string name, string doc, bool isBuiltin, bool isStatic, IMemberContainer declaringType) { _name = name; _doc = doc; _isBuiltin = isBuiltin; _isStatic = isStatic; _declaringModule = CPythonModule.GetDeclaringModuleFromContainer(declaringType); _declaringType = declaringType as IPythonType; _overloads = new List<IPythonFunctionOverload>(); }
public AstPythonType(PythonAst ast, IPythonModule declModule, ClassDefinition def, string doc, LocationInfo loc) { _members = new Dictionary<string, IMember>(); Name = def.Name; Documentation = doc; DeclaringModule = declModule; Mro = new IPythonType[0]; Locations = new[] { loc }; }
public SequenceBuiltinClassInfo(IPythonType classObj, PythonAnalyzer projectState) : base(classObj, projectState) { var seqType = classObj as IPythonSequenceType; if (seqType != null && seqType.IndexTypes != null) { _indexTypes = projectState.GetAnalysisSetFromObjects(seqType.IndexTypes).GetInstanceType(); } else { _indexTypes = AnalysisSet.Empty; } }
public CPythonSequenceType(IPythonType baseType, ITypeDatabaseReader typeDb, List<object> indexTypes) { _type = baseType; if (indexTypes != null) { _indexTypes = new List<IPythonType>(); foreach (var indexType in indexTypes) { typeDb.LookupType(indexType, type => _indexTypes.Add(type)); } } }
public IList<IPythonType> GetEventParameterTypes() { if (_parameterTypes == null) { var types = Interpreter.Remote.GetEventParameterPythonTypes(Value); var paramTypes = new IPythonType[types.Length]; for (int i = 0; i < paramTypes.Length; i++) { paramTypes[i] = Interpreter.GetTypeFromType(types[i]); } _parameterTypes = paramTypes; } return _parameterTypes; }
public IList<IPythonType> GetEventParameterTypes() { if (_parameterTypes == null) { var ri = RemoteInterpreter; var types = ri != null ? ri.GetEventParameterPythonTypes(Value) : new ObjectIdentityHandle[0]; var paramTypes = new IPythonType[types.Length]; for (int i = 0; i < paramTypes.Length; i++) { paramTypes[i] = Interpreter.GetTypeFromType(types[i]); } _parameterTypes = paramTypes; } return _parameterTypes; }
public CPythonProperty(ITypeDatabaseReader typeDb, Dictionary<string, object> valueDict, IMemberContainer container) { _declaringModule = CPythonModule.GetDeclaringModuleFromContainer(container); object value; if (valueDict.TryGetValue("doc", out value)) { _doc = value as string; } object type; if (!valueDict.TryGetValue("type", out type) || type == null) { type = new[] { null, "object" }; } _hasLocation = PythonTypeDatabase.TryGetLocation(valueDict, ref _line, ref _column); typeDb.LookupType(type, typeValue => _type = typeValue); }
public AstPythonFunction(PythonAst ast, IPythonModule declModule, IPythonType declType, FunctionDefinition def, string doc) { DeclaringModule = declModule; DeclaringType = declType; Name = def.Name; Documentation = doc; foreach (var dec in (def.Decorators?.Decorators).MaybeEnumerate().OfType<NameExpression>()) { if (dec.Name == "classmethod") { IsClassMethod = true; } else if (dec.Name == "staticmethod") { IsStatic = true; } } _overloads = new List<AstPythonFunctionOverload> { new AstPythonFunctionOverload(Documentation, "", MakeParameters(ast, def), MakeReturns(def)) }; }
public MemberAssertions(IMember member) { Subject = member; Type = Subject.GetPythonType(); }
private static List<IPythonType> GetOldStyleMro(IPythonType oldStyleType) { List<IPythonType> res = new List<IPythonType>(); GetOldStyleMroWorker(oldStyleType, res); return res; }
public static void CreateExceptionMapping(IPythonType baseType, ExceptionMapping em) { IPythonType type = CreatePythonException(em.PythonException, em.PythonModule, baseType, em.Creator); pythonToClr[type] = em.ClrException; clrToPython[em.ClrException] = type; if (em.Subtypes != null) { for (int i = 0; i < em.Subtypes.Count; i++) { CreateExceptionMapping(type, em.Subtypes[i]); } } }
/// <summary> /// Creates and returns the IPythonType for a given PythonException in a given module with a given base type using a given exception creator. /// Throws InvalidOperationException if it already exists and has a different base type. /// /// Note that specifying the module doesn't actually place the created type in that module. /// The type knows about the module, but the module doesn't know about the type. It's the caller's /// responsibility to put the returned type in the appropriate module. /// </summary> public static IPythonType CreatePythonException(string name, string module, IPythonType baseType, ExceptionClassCreator creator) { IPythonType type; QualifiedExceptionName key = new QualifiedExceptionName(name, module); if (nameToPython.TryGetValue(key, out type)) { if (Ops.Equals(type.BaseClasses, ObjectToTuple(baseType))) { return type; } else { throw new InvalidOperationException(module + "." + name + " already exists with different base type(s)"); } } IPythonType res = creator(name, module, baseType); nameToPython[key] = res; return res; }
public CPythonConstant(IPythonType type) { _type = type; }
public IPythonType MakeGenericType(IPythonType[] indexTypes) { // TODO: Caching? ObjectIdentityHandle[] types = new ObjectIdentityHandle[indexTypes.Length]; for (int i = 0; i < types.Length; i++) { types[i] = ((IronPythonType)indexTypes[i]).Value; } var ri = RemoteInterpreter; return ri != null ? Interpreter.GetTypeFromType(ri.TypeGroupMakeGenericType(Value, types)) : null; }
/// <summary> /// Creates type info for a list-like strongly typed collection, such as List[T]. /// </summary> /// <param name="typeName">Type name.</param> /// <param name="typeId">Collection type id. Can be used when list is used to simulate other collections, like a set.</param> /// <param name="itemType">List item type.</param> /// <param name="interpreter">Python interpreter</param> /// <param name="isMutable">Tells of list represents a mutable collection.</param> /// <param name="formatName">If true, type will append item type names to the base type name.</param> public TypingListType(string typeName, BuiltinTypeId typeId, IPythonType itemType, IPythonInterpreter interpreter, bool isMutable, bool formatName = true) : base(null, typeId, interpreter, isMutable) { ItemType = itemType; Name = formatName ? $"{typeName}[{itemType.Name}]" : typeName; }
public RangeInfo(IPythonType seqType, PythonAnalyzer state) : base(state.ClassInfos[BuiltinTypeId.List]) { }
public Hover GetHover(IDocumentAnalysis analysis, SourceLocation location) { if (analysis is EmptyAnalysis) { return(new Hover { contents = Resources.AnalysisIsInProgressHover }); } ExpressionLocator.FindExpression(analysis.Ast, location, FindExpressionOptions.Hover, out var node, out var statement, out var hoverScopeStatement); if (!HasHover(node) || !(node is Expression expr)) { return(null); } var range = new Range { start = expr.GetStart(analysis.Ast), end = expr.GetEnd(analysis.Ast) }; var eval = analysis.ExpressionEvaluator; switch (statement) { case FromImportStatement fi when node is NameExpression nex: { var contents = HandleFromImport(fi, location, hoverScopeStatement, analysis); if (contents != null) { return(new Hover { contents = contents, range = range }); } break; } case ImportStatement imp: { var contents = HandleImport(imp, location, hoverScopeStatement, analysis); if (contents != null) { return(new Hover { contents = contents, range = range }); } break; } } IMember value; IPythonType type; using (eval.OpenScope(analysis.Document, hoverScopeStatement)) { // Here we can be hovering over a class member. Class members are declared // as members as well as special variables in the class scope. If this is // a name expression (rather than a member expression) and it is a class // variable NOT in the immediate class scope, filter it out. Consider: // class A: // x = 1 // y = x // hover over 'x' in 'y = x' should produce proper tooltip. However, in // class A: // x = 1 // def func(self): // y = x // hover over 'x' in 'y = x' should not produce tooltip. IVariable variable = null; if (expr is NameExpression nex) { eval.LookupNameInScopes(nex.Name, out _, out variable, LookupOptions.All); if (IsInvalidClassMember(variable, hoverScopeStatement, location.ToIndex(analysis.Ast))) { return(null); } } value = variable?.Value ?? eval.GetValueFromExpression(expr, LookupOptions.All); type = value?.GetPythonType(); if (type == null) { return(null); } } IPythonType self = null; string name = null; // If expression is A.B, trim applicable span to 'B'. if (expr is MemberExpression mex) { name = mex.Name; range = new Range { start = mex.Target.GetEnd(analysis.Ast), end = range.end }; // In case of a member expression get the target since if we end up with method // of a generic class, the function will need specific type to determine its return // value correctly. I.e. in x.func() we need to determine type of x (self for func). var v = eval.GetValueFromExpression(mex.Target); self = v?.GetPythonType(); } // Figure out name, if any name = name ?? (node as NameExpression)?.Name; // Special case hovering over self or cls if ((name.EqualsOrdinal("self") || name.EqualsOrdinal("cls")) && type is IPythonClassType) { return(new Hover { contents = _docSource.GetHover(null, type), range = range }); } name = name == null && statement is ClassDefinition cd ? cd.Name : name; name = name == null && statement is FunctionDefinition fd ? fd.Name : name; return(new Hover { contents = _docSource.GetHover(name, value, self), range = range }); }
/// <summary> /// Creates type info for a list-like strongly typed collection, such as List[T]. /// </summary> /// <param name="typeName">Type name.</param> /// <param name="itemType">List item type.</param> /// <param name="interpreter">Python interpreter</param> /// <param name="isMutable">Tells of list represents a mutable collection.</param> /// <param name="formatName">If true, type will append item type names to the base type name.</param> public TypingListType(string typeName, IPythonType itemType, IPythonInterpreter interpreter, bool isMutable, bool formatName = true) : this(typeName, BuiltinTypeId.List, itemType, interpreter, isMutable, formatName) { }
public MarkupContent GetHover(string name, IMember member, IPythonType self, bool includeClassInit = false) { // We need to tell between instance and type. var type = member.GetPythonType(); if (type.IsUnknown()) { return(new MarkupContent { kind = MarkupKind.Markdown, value = $"```\n{name}\n```" }); } string text; if (member is IPythonInstance) { if (!(type is IPythonFunctionType)) { text = !string.IsNullOrEmpty(name) ? $"{name}: {type.Name}" : $"{type.Name}"; return(new MarkupContent { kind = MarkupKind.Markdown, value = $"```\n{text}\n```" }); } } var typeDoc = !string.IsNullOrEmpty(type.Documentation) ? $"\n---\n{type.MarkdownDoc()}" : string.Empty; switch (type) { case IPythonPropertyType prop: text = GetPropertyString(prop); break; case IPythonFunctionType ft: text = GetFunctionString(ft, self); break; case IPythonClassType cls: var clsDoc = !string.IsNullOrEmpty(cls.Documentation) ? $"\n---\n{cls.MarkdownDoc()}" : string.Empty; string className; var sig = string.Empty; if (includeClassInit) { className = cls.Name; var init = cls.TryGetFunctionType(); if (init != null) { sig = GetSignatureString(init, null, out var _, 0, "", true); } } else { className = "class " + cls.Name; } text = $"```\n{className}{sig}\n```{clsDoc}"; break; case IPythonModule mod: text = !string.IsNullOrEmpty(mod.Name) ? $"```\nmodule {mod.Name}\n```{typeDoc}" : $"`module`{typeDoc}"; break; default: text = !string.IsNullOrEmpty(name) ? $"```\ntype {name}: {type.Name}\n```{typeDoc}" : $"{type.Name}{typeDoc}"; break; } return(new MarkupContent { kind = MarkupKind.Markdown, value = text }); }
public AstPythonProperty(FunctionDefinition fd, IPythonModule declaringModule, IPythonType declaringType, ILocationInfo location) : base(fd.Name, declaringModule, null, location) { FunctionDefinition = fd; DeclaringType = declaringType; }
public IPythonType GetTypeFromLiteral(Expression expr) { if (expr is ConstantExpression ce) { if (ce.Value == null) { return(Interpreter.GetBuiltinType(BuiltinTypeId.None)); } switch (Type.GetTypeCode(ce.Value.GetType())) { case TypeCode.Boolean: return(Interpreter.GetBuiltinType(BuiltinTypeId.Bool)); case TypeCode.Double: return(Interpreter.GetBuiltinType(BuiltinTypeId.Float)); case TypeCode.Int32: return(Interpreter.GetBuiltinType(BuiltinTypeId.Int)); case TypeCode.String: return(Interpreter.GetBuiltinType(BuiltinTypeId.Unicode)); case TypeCode.Object: switch (ce.Value) { case Complex _: return(Interpreter.GetBuiltinType(BuiltinTypeId.Complex)); case AsciiString _: return(Interpreter.GetBuiltinType(BuiltinTypeId.Bytes)); case BigInteger _: return(Interpreter.GetBuiltinType(BuiltinTypeId.Long)); case Ellipsis _: return(Interpreter.GetBuiltinType(BuiltinTypeId.Ellipsis)); } break; } return(null); } if (expr is ListExpression || expr is ListComprehension) { return(Interpreter.GetBuiltinType(BuiltinTypeId.List)); } if (expr is DictionaryExpression || expr is DictionaryComprehension) { return(Interpreter.GetBuiltinType(BuiltinTypeId.Dict)); } if (expr is TupleExpression tex) { var types = tex.Items .Select(x => { IPythonType value = null; if (x is NameExpression ne) { value = GetInScope(ne.Name)?.GetPythonType(); } return(value ?? UnknownType); }).ToArray(); var res = Interpreter.GetBuiltinType(BuiltinTypeId.Tuple); if (types.Length > 0) { var iterRes = Interpreter.GetBuiltinType(BuiltinTypeId.TupleIterator); //res = new PythonSequence(res, Module, types, iterRes); } return(res); } if (expr is SetExpression || expr is SetComprehension) { return(Interpreter.GetBuiltinType(BuiltinTypeId.Set)); } if (expr is BackQuoteExpression && Interpreter.LanguageVersion.Is2x()) { return(Interpreter.GetBuiltinType(BuiltinTypeId.Bytes)); } return(expr is LambdaExpression?Interpreter.GetBuiltinType(BuiltinTypeId.Function) : null); }
public static Tuple Calculate(IPythonType startingType, Tuple bases) { return Calculate(startingType, bases, false); }
/// <summary> /// Creates delegate type wrapper over an existing type. /// Use dedicated constructor for wrapping builtin types. /// </summary> public PythonTypeWrapper(IPythonType type) : this(type, type.DeclaringModule) { }
private bool GetSequenceTypes(string name, IReadOnlyList <IAnalysisSet> args, out IPythonType realType, out IAnalysisSet keyTypes, out IAnalysisSet valueTypes) { switch (name) { case "List": case "Container": case "Sequence": case "MutableSequence": realType = Types[BuiltinTypeId.List]; keyTypes = ClassInfo[BuiltinTypeId.Int].Instance; valueTypes = AnalysisSet.UnionAll(args.Select(ToInstance)); return(true); case "Tuple": realType = Types[BuiltinTypeId.Tuple]; keyTypes = ClassInfo[BuiltinTypeId.Int].Instance; valueTypes = AnalysisSet.UnionAll(args.Select(ToInstance)); return(true); case "MutableSet": case "Set": realType = Types[BuiltinTypeId.Set]; keyTypes = null; valueTypes = AnalysisSet.UnionAll(args.Select(ToInstance)); return(true); case "FrozenSet": realType = Types[BuiltinTypeId.FrozenSet]; keyTypes = null; valueTypes = AnalysisSet.UnionAll(args.Select(ToInstance)); return(true); case "KeysView": if (args.Count >= 1) { realType = Types[BuiltinTypeId.DictKeys]; keyTypes = null; valueTypes = AnalysisSet.UnionAll(GetTypeList(args[0]).Select(ToInstance)); return(true); } break; case "ValuesView": if (args.Count >= 1) { realType = Types[BuiltinTypeId.DictValues]; keyTypes = null; valueTypes = AnalysisSet.UnionAll(GetTypeList(args[0]).Select(ToInstance)); return(true); } break; case "ItemsView": if (args.Count >= 2) { realType = Types[BuiltinTypeId.DictItems]; keyTypes = null; valueTypes = MakeTuple( AnalysisSet.UnionAll(GetTypeList(args[0]).Select(ToInstance)), AnalysisSet.UnionAll(GetTypeList(args[1]).Select(ToInstance)) ); return(true); } break; case "Dict": case "Mapping": if (args.Count >= 2) { realType = Types[BuiltinTypeId.Dict]; keyTypes = AnalysisSet.UnionAll(GetTypeList(args[0]).Select(ToInstance)); valueTypes = AnalysisSet.UnionAll(GetTypeList(args[1]).Select(ToInstance)); return(true); } break; } realType = null; keyTypes = null; valueTypes = null; return(false); }
/// <summary> /// Creates delegate type wrapper over an existing type. /// Use dedicated constructor for wrapping builtin types. /// </summary> public PythonTypeWrapper(IPythonType type, IPythonModule declaringModule) { _innerType = type ?? throw new ArgumentNullException(nameof(type)); DeclaringModule = declaringModule; }
/// <summary> /// Calculates MRO according to https://www.python.org/download/releases/2.3/mro/ /// </summary> internal static IReadOnlyList <IPythonType> CalculateMro(IPythonType type, HashSet <IPythonType> recursionProtection = null) { if (type == null) { return(Array.Empty <IPythonType>()); } recursionProtection = recursionProtection ?? new HashSet <IPythonType>(); if (!recursionProtection.Add(type)) { return(Array.Empty <IPythonType>()); } var bases = (type as IPythonClassType)?.Bases; if (bases == null) { var members = (type.GetMember("__bases__") as IPythonCollection)?.Contents ?? Array.Empty <IMember>(); bases = members.Select(m => m.GetPythonType()).ToArray(); } try { var mergeList = new List <List <IPythonType> > { new List <IPythonType>() }; var finalMro = new List <IPythonType> { type }; var mros = bases.Select(b => CalculateMro(b, recursionProtection).ToList()); mergeList.AddRange(mros); 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[] { type }); } 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(type); } }
public ImportInfo(bool moduleImported, bool memberImported, IPythonType symbol) : this(moduleImported, memberImported, symbol.MemberType == PythonMemberType.Module) { Symbol = symbol; }
internal CPythonConstant GetConstant(IPythonType type) { CPythonConstant constant; if (_constants.TryGetValue(type, out constant)) { return constant; } _constants[type] = constant = new CPythonConstant(type); return constant; }
private void MergeClass(IVariable v, IPythonClassType sourceClass, IPythonType stubType, CancellationToken cancellationToken) { // Transfer documentation first so we get class documentation // that comes from the class definition win over one that may // come from __init__ during the member merge below. TransferDocumentationAndLocation(sourceClass, stubType); // Replace the class entirely since stub members may use generic types // and the class definition is important. We transfer missing members // from the original class to the stub. _eval.DeclareVariable(v.Name, v.Value, v.Source); // First pass: go through source class members and pick those // that are not present in the stub class. foreach (var name in sourceClass.GetMemberNames().ToArray()) { cancellationToken.ThrowIfCancellationRequested(); var sourceMember = sourceClass.GetMember(name); if (sourceMember.IsUnknown()) { continue; // Do not add unknowns to the stub. } var sourceMemberType = sourceMember?.GetPythonType(); if (sourceMemberType is IPythonClassMember cm && cm.DeclaringType != sourceClass) { continue; // Only take members from this class and not from bases. } if (!IsFromThisModuleOrSubmodules(sourceMemberType)) { continue; // Member does not come from module or its submodules. } var stubMember = stubType.GetMember(name); var stubMemberType = stubMember.GetPythonType(); // Get documentation from the current type, if any, since stubs // typically do not contain documentation while scraped code does. TransferDocumentationAndLocation(sourceMemberType, stubMemberType); // If stub says 'Any' but we have better type, use member from the original class. if (stubMember != null && !(stubType.DeclaringModule is TypingModule && stubType.Name == "Any")) { continue; // Stub already have the member, don't replace. } (stubType as PythonType)?.AddMember(name, stubMember, overwrite: true); } // Second pass: go through stub class members and if they don't have documentation // or location, check if source class has same member and fetch it from there. // The reason is that in the stub sometimes members are specified all in one // class while in source they may come from bases. Example: datetime. foreach (var name in stubType.GetMemberNames().ToArray()) { cancellationToken.ThrowIfCancellationRequested(); var stubMember = stubType.GetMember(name); if (stubMember.IsUnknown()) { continue; } var stubMemberType = stubMember.GetPythonType(); if (stubMemberType is IPythonClassMember cm && cm.DeclaringType != stubType) { continue; // Only take members from this class and not from bases. } var sourceMember = sourceClass.GetMember(name); if (sourceMember.IsUnknown()) { continue; } var sourceMemberType = sourceMember.GetPythonType(); if (sourceMemberType.Location.IsValid && !stubMemberType.Location.IsValid) { TransferDocumentationAndLocation(sourceMemberType, stubMemberType); } } }
protected void DeclareBuiltinVariable(string name, IPythonType type, Location location) => VariableCollection.DeclareVariable(name, type, VariableSource.Builtin, location);
internal CPythonConstant GetConstant(IPythonType type) { return(_sharedState.GetConstant(type)); }
/// <summary> /// Creates and returns the IPythonType for a given PythonException in a given module with a given base type. /// Throws InvalidOperationException if it already exists and has a different base type. /// /// Note that specifying the module doesn't actually place the created type in that module. /// The type knows about the module, but the module doesn't know about the type. It's the caller's /// responsibility to put the returned type in the appropriate module. /// </summary> public static IPythonType CreatePythonException(string name, string module, IPythonType baseType) { return CreatePythonException(name, module, baseType, DefaultExceptionCreator); }
/// <summary> /// Looks up a type and queues a fixup if the type is not yet available. /// Receives a delegate which assigns the value to the appropriate field. /// </summary> public void LookupType(object typeRefOrList, Action <IPythonType> assign) { var typeRef = typeRefOrList as object[]; if (typeRef != null && typeRef.Length >= 2) { string modName = null, typeName = null; List <object> indexTypes = null; IPythonType res = null; modName = typeRef[0] as string; typeName = typeRef[1] as string; if (typeRef.Length > 2) { indexTypes = typeRef[2] as List <object>; } if (typeName == null) { Debug.Assert(modName == null, "moduleref should not be passed to LookupType"); AddObjectTypeFixup(assign); return; } else { IPythonModule module; if (modName == null) { res = BuiltinModule.GetAnyMember(typeName) as IPythonType; if (res != null) { assign(res); } else { AddObjectTypeFixup(assign); } } else { string alternateTypeName = typeName; module = GetModuleOrClass(modName, ref alternateTypeName); if (module == null) { AddFixup(() => { // Fixup 1: Module was not found. var mod2 = GetModuleOrClass(modName, ref alternateTypeName); if (mod2 != null) { AssignMemberFromModule(mod2, alternateTypeName, null, indexTypes, assign, true); } }); return; } AssignMemberFromModule(module, alternateTypeName, null, indexTypes, assign, true); } } return; } var multiple = typeRefOrList as List <object>; if (multiple != null) { foreach (var typeInfo in multiple) { LookupType(typeInfo, assign); } } }
private static Type GetCLRTypeFromPython(IPythonType type) { Type clrType; if (pythonToClr.TryGetValue(type, out clrType)) { return clrType; } // unknown type... try walking the type hierarchy and // throwing the closest match. Tuple curType = Ops.GetAttr(DefaultContext.Default, type, SymbolTable.Bases) as Tuple; if (curType != null) { for (int i = 0; i < curType.Count; i++) { clrType = GetCLRTypeFromPython(curType[i] as IPythonType); if (clrType != null) return clrType; } } return typeof(Exception); }
public DictBuiltinClassInfo(IPythonType classObj, PythonAnalyzer projectState) : base(classObj, projectState) { }
private static List<IPythonType> GetNewStyleMro(IPythonType oldStyleType) { List<IPythonType> res = new List<IPythonType>(); res.Add(oldStyleType); foreach (IPythonType dt in oldStyleType.BaseClasses) { res.AddRange(TupleToList(Calculate(dt, dt.BaseClasses, true))); } return res; }
internal BuiltinClassInfo GetBuiltinType(IPythonType type) { return((BuiltinClassInfo)GetCached(type, () => MakeBuiltinType(type) ) ?? ClassInfos[BuiltinTypeId.Object]); }
private static void GetOldStyleMroWorker(IPythonType curType, List<IPythonType> res) { if (!res.Contains(curType)) { res.Add(curType); foreach (IPythonType dt in curType.BaseClasses) { GetOldStyleMroWorker(dt, res); } } }
internal static IList <IPythonType> CalculateMro(IPythonType cls, HashSet <IPythonType> recursionProtection = null) { if (cls == null) { return(Array.Empty <IPythonType>()); } if (recursionProtection == null) { recursionProtection = new HashSet <IPythonType>(); } if (!recursionProtection.Add(cls)) { return(Array.Empty <IPythonType>()); } try { var mergeList = new List <List <IPythonType> > { new List <IPythonType>() }; var finalMro = new List <IPythonType> { cls }; var bases = (cls as AstPythonType)?.Bases ?? (cls.GetMember(null, "__bases__") as IPythonSequenceType)?.IndexTypes ?? Array.Empty <IPythonType>(); foreach (var b in bases) { var b_mro = new List <IPythonType>(); 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); } }
/// <summary> /// </summary> public static Tuple Calculate(IPythonType startingType, Tuple bases, bool forceNewStyle) { if (bases.ContainsValue(startingType)) { throw Ops.TypeError("a __bases__ item causes an inheritance cycle"); } List<IPythonType> mro = new List<IPythonType>(); mro.Add(startingType); if (bases.Count != 0) { List<List<IPythonType>> mroList = new List<List<IPythonType>>(); // build up the list - it contains the MRO of all our // bases as well as the bases themselves in the order in // which they appear. int oldSytleCount = 0; foreach (IPythonType type in bases) { if (!(type is DynamicType)) oldSytleCount++; } foreach (IPythonType type in bases) { DynamicType dt = type as DynamicType; if (dt != null) { mroList.Add(TupleToList(dt.MethodResolutionOrder)); } else if (oldSytleCount == 1 && !forceNewStyle) { mroList.Add(GetOldStyleMro(type)); } else { mroList.Add(GetNewStyleMro(type)); } } mroList.Add(TupleToList(bases)); int lastRemove = -1; for (; ; ) { bool removed = false, sawNonZero = false; // now that we have our list, look for good heads for (int i = 0; i < mroList.Count; i++) { if (mroList[i].Count == 0) continue; // we've removed everything from this list. sawNonZero = true; IPythonType head = mroList[i][0]; // see if we're in the tail of any other lists... bool inTail = false; for (int j = 0; j < mroList.Count; j++) { if (mroList[j].Count != 0 && !mroList[j][0].Equals(head) && mroList[j].Contains(head)) { inTail = true; break; } } if (!inTail) { lastRemove = i; if (mro.Contains(head)) { throw Ops.TypeError("a __bases__ item causes an inheritance cycle"); } // add it to the linearization, and remove // it from our lists mro.Add(head); for (int j = 0; j < mroList.Count; j++) { mroList[j].Remove(head); } removed = true; break; } } if (!sawNonZero) break; if (!removed) { // we've iterated through the list once w/o removing anything throw Ops.TypeError("invalid order for base classes: {0} {1}", mroList[0][0], mroList[1][0]); } } } return new Tuple(mro); }
public static bool IsGeneric(this IPythonType value) => value is IGenericTypeParameter || (value is IGenericType gt && gt.IsGeneric);
private PythonPropertyType AddProperty(FunctionDefinition node, IPythonModule declaringModule, IPythonType declaringType, bool isAbstract, LocationInfo loc) { if (!(_eval.LookupNameInScopes(node.Name, LookupOptions.Local) is PythonPropertyType existing)) { existing = new PythonPropertyType(node, declaringModule, declaringType, isAbstract, loc); _eval.DeclareVariable(node.Name, existing, VariableSource.Declaration, loc); } AddOverload(node, existing, o => existing.AddOverload(o)); return(existing); }
public ClassView(IModuleContext context, string name, IPythonType member) : base(context, name, member) { _type = member; }
public TupleBuiltinClassInfo(IPythonType classObj, PythonAnalyzer projectState) : base(classObj, projectState) { _tupleTypes = (classObj as IPythonSequenceType)?.IndexTypes?.Select(projectState.GetAnalysisValueFromObjects).ToArray(); }
private void SpecializeTypes() { var isV3 = Interpreter.LanguageVersion.Is3x(); foreach (BuiltinTypeId typeId in Enum.GetValues(typeof(BuiltinTypeId))) { var m = GetMember("__{0}__".FormatInvariant(typeId)); if (!(m is PythonType biType && biType.IsBuiltin)) { continue; } if (biType.IsUnknown()) { // Under no circumstances we modify the unknown type. continue; } if (biType.IsHidden) { _hiddenNames.Add(biType.Name); } _hiddenNames.Add("__{0}__".FormatInvariant(typeId)); // In V2 Unicode string is 'Unicode' and regular string is 'Str' or 'Bytes'. // In V3 Unicode and regular strings are 'Str' and ASCII/byte string is 'Bytes'. switch (typeId) { case BuiltinTypeId.Bytes: { var id = !isV3 ? BuiltinTypeId.Str : BuiltinTypeId.Bytes; biType.TrySetTypeId(id); biType.AddMember(@"__iter__", BuiltinsSpecializations.__iter__(Interpreter, id), true); break; } case BuiltinTypeId.BytesIterator: { biType.TrySetTypeId(!isV3 ? BuiltinTypeId.StrIterator : BuiltinTypeId.BytesIterator); break; } case BuiltinTypeId.Unicode: { var id = isV3 ? BuiltinTypeId.Str : BuiltinTypeId.Unicode; biType.TrySetTypeId(id); biType.AddMember(@"__iter__", BuiltinsSpecializations.__iter__(Interpreter, id), true); break; } case BuiltinTypeId.UnicodeIterator: { biType.TrySetTypeId(isV3 ? BuiltinTypeId.StrIterator : BuiltinTypeId.UnicodeIterator); break; } case BuiltinTypeId.Str: { biType.AddMember(@"__iter__", BuiltinsSpecializations.__iter__(Interpreter, typeId), true); } break; case BuiltinTypeId.Unknown: break; default: biType.TrySetTypeId(typeId); switch (typeId) { case BuiltinTypeId.Bool: _boolType = _boolType ?? biType; break; } break; } } _hiddenNames.Add("__builtin_module_names__"); var location = new Location(this); if (_boolType != null) { Analysis.GlobalScope.DeclareVariable("True", _boolType, VariableSource.Builtin, location); Analysis.GlobalScope.DeclareVariable("False", _boolType, VariableSource.Builtin, location); } Analysis.GlobalScope.DeclareVariable("None", new PythonNone(this), VariableSource.Builtin, location); foreach (var n in GetMemberNames()) { var t = GetMember(n).GetPythonType(); if (t.TypeId == BuiltinTypeId.Unknown && t.MemberType != PythonMemberType.Unknown) { if (t is PythonType pt) { pt.TrySetTypeId(BuiltinTypeId.Type); // For Python 3+ make sure base is object } } } }
public IronPythonConstructorFunction(IronPythonInterpreter interpreter, ObjectIdentityHandle[] infos, IPythonType type) { _interpreter = interpreter; _infos = infos; _type = type; }
private object MakeInstance(ICallerContext context, IPythonType cls, object[] args) { if (cls is OldClass) { OldInstance inst = new OldInstance((OldClass)cls); if (args.Length != 0 || Ops.HasAttr(context, cls, SymbolTable.GetInitArgs)) { Ops.Call(Ops.GetAttr(context, inst, SymbolTable.Init), args); } return inst; } return Ops.Call(cls, args); }
public static bool IsGenericParameter(this IPythonType value) => value is IGenericTypeParameter;
public IList<IPythonType> GetTypesPropagatedOnCall() { if (_eventInvokeArgs == null) { var ri = RemoteInterpreter; var types = ri != null ? ri.GetTypeGroupEventInvokeArgs(Value) : null; if (types == null) { _eventInvokeArgs = IronPythonType.EmptyTypes; } else { var args = new IPythonType[types.Length]; for (int i = 0; i < types.Length; i++) { args[i] = Interpreter.GetTypeFromType(types[i]); } _eventInvokeArgs = args; } } return _eventInvokeArgs == IronPythonType.EmptyTypes ? null : _eventInvokeArgs; }
internal BuiltinInstanceInfo GetInstance(IPythonType type) { return(GetBuiltinType(type).Instance); }
public Argument(string name, ParameterKind kind, Expression valueValueExpression, IPythonType type, Node location) { Name = name; Kind = kind; Type = type; ValueExpression = valueValueExpression; Location = location; }
internal CPythonConstant GetConstant(IPythonType type) { return _sharedState.GetConstant(type); }
public Argument(IPythonType type) : this(type.Name, type) { }