public void EvaluateClass() { // Open class scope chain using (Eval.OpenScope(Module, _classDef, out var outerScope)) { var instance = Eval.GetInScope(_classDef.Name, outerScope); if (!(instance?.GetPythonType() is PythonClassType classInfo)) { if (instance != null) { // TODO: warning that variable is already declared of a different type. } return; } // Evaluate inner classes, if any EvaluateInnerClasses(_classDef); _class = classInfo; var bases = ProcessBases(); _class.SetBases(bases, Eval.CurrentScope); _class.DecideGeneric(); // Declare __class__ variable in the scope. Eval.DeclareVariable("__class__", _class, VariableSource.Declaration); ProcessClassBody(); } }
public async Task Mro() { using (var s = await CreateServicesAsync(null, null, null)) { var interpreter = s.GetService <IPythonInterpreter>(); var o = interpreter.GetBuiltinType(BuiltinTypeId.Object); var m = new SentinelModule("test", s); var location = new Location(m); var O = new PythonClassType("O", location); var A = new PythonClassType("A", location); var B = new PythonClassType("B", location); var C = new PythonClassType("C", location); var D = new PythonClassType("D", location); var E = new PythonClassType("E", location); var F = new PythonClassType("F", location); O.SetBases(new[] { o }); F.SetBases(new[] { O }); E.SetBases(new[] { O }); D.SetBases(new[] { O }); C.SetBases(new[] { D, F }); B.SetBases(new[] { D, E }); A.SetBases(new[] { B, C }); var mroA = PythonClassType.CalculateMro(A).Select(p => p.Name); mroA.Should().Equal("A", "B", "C", "D", "E", "F", "O", "object"); var mroB = PythonClassType.CalculateMro(B).Select(p => p.Name); mroB.Should().Equal("B", "D", "E", "O", "object"); var mroC = PythonClassType.CalculateMro(C).Select(p => p.Name); mroC.Should().Equal("C", "D", "F", "O", "object"); } }
public PythonLazyClassType(ClassModel model, ModuleFactory mf, IGlobalScope gs, IPythonType declaringType) : base(model, mf, gs, declaringType) { _cls = new PythonClassType(model.Name, new Location(mf.Module, model.IndexSpan.ToSpan())); _cls.SetDocumentation(model.Documentation); SetInnerType(_cls); }
public override IMember Create(ModuleFactory mf, IPythonType declaringType, IGlobalScope gs) { if (_cls != null) { return(_cls); } _cls = new PythonClassType(Name, new Location(mf.Module, IndexSpan.ToSpan())); var bases = CreateBases(mf, gs); _cls.SetBases(bases); _cls.SetDocumentation(Documentation); if (GenericParameterValues.Length > 0) { _cls.StoreGenericParameters( _cls, _cls.GenericParameters.Keys.ToArray(), GenericParameterValues.ToDictionary( k => _cls.GenericParameters.Keys.First(x => x == k.Name), v => mf.ConstructType(v.Type) ) ); } var all = Classes.Concat <MemberModel>(Properties).Concat(Methods).Concat(Fields); foreach (var m in all) { _cls.AddMember(m.Name, m.Create(mf, _cls, gs), false); } return(_cls); }
private PythonClassType CreateClass(ClassDefinition cd) { var cls = new PythonClassType(cd, _eval.GetLocationOfName(cd), _eval.SuppressBuiltinLookup ? BuiltinTypeId.Unknown : BuiltinTypeId.Type); _typeMap[cd] = cls; return(cls); }
private PythonClassType CreateClass(ClassDefinition node) { var cls = new PythonClassType(node, _eval.Module, GetLoc(node), _eval.SuppressBuiltinLookup ? BuiltinTypeId.Unknown : BuiltinTypeId.Type); _typeMap[node] = cls; return(cls); }
/// <summary> /// Given generic class type and the passed constructor arguments /// creates specific type and instance of the type. Attempts to match /// supplied arguments to either __init__ signature or to the /// list of generic definitions in Generic[T1, T2, ...]. /// </summary> private IMember CreateClassInstance(PythonClassType cls, IReadOnlyList <IMember> constructorArguments, CallExpression callExpr) { // Look at the constructor arguments and create argument set // based on the __init__ definition. var initFunc = cls.GetMember(@"__init__") as IPythonFunctionType; var initOverload = initFunc?.DeclaringType == cls?initFunc.Overloads.FirstOrDefault() : null; var argSet = initOverload != null ? new ArgumentSet(initFunc, 0, null, callExpr, this) : new ArgumentSet(constructorArguments, callExpr, this); argSet.Evaluate(); var specificType = cls.CreateSpecificType(argSet); return(new PythonInstance(specificType)); }
private PythonClassType CreateClass(ClassDefinition cd) { PythonType declaringType = null; if (!(cd.Parent is PythonAst)) { Debug.Assert(_typeMap.ContainsKey(cd.Parent)); _typeMap.TryGetValue(cd.Parent, out declaringType); } var cls = new PythonClassType(cd, declaringType, _eval.GetLocationOfName(cd), _eval.SuppressBuiltinLookup ? BuiltinTypeId.Unknown : BuiltinTypeId.Type); _typeMap[cd] = cls; declaringType?.AddMember(cls.Name, cls, overwrite: true); return(cls); }
public async Task EvaluateClassAsync(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); // Open class scope chain using (Eval.OpenScope(_classDef, out var outerScope)) { var instance = Eval.GetInScope(_classDef.Name, outerScope); if (!(instance?.GetPythonType() is PythonClassType classInfo)) { if (instance != null) { // TODO: warning that variable is already declared of a different type. } // May be odd case like class inside a class. return; } // Evaluate inner classes, if any await EvaluateInnerClassesAsync(_classDef, cancellationToken); _class = classInfo; // Set bases to the class. var bases = new List <IPythonType>(); foreach (var a in _classDef.Bases.Where(a => string.IsNullOrEmpty(a.Name))) { // We cheat slightly and treat base classes as annotations. var b = await Eval.GetTypeFromAnnotationAsync(a.Expression, cancellationToken); if (b != null) { bases.Add(b.GetPythonType()); } } _class.SetBases(Interpreter, bases); // Declare __class__ variable in the scope. Eval.DeclareVariable("__class__", _class, _classDef); await ProcessClassBody(cancellationToken); } }
public void EvaluateClass() { // Open class scope chain using (Eval.OpenScope(Module, _classDef, out var outerScope)) { var instance = Eval.GetInScope(_classDef.Name, outerScope); if (!(instance?.GetPythonType() is PythonClassType classInfo)) { if (instance != null) { // TODO: warning that variable is already declared of a different type. } return; } // Evaluate inner classes, if any EvaluateInnerClasses(_classDef); _class = classInfo; // Set bases to the class. var bases = new List <IPythonType>(); foreach (var a in _classDef.Bases.Where(a => string.IsNullOrEmpty(a.Name))) { // We cheat slightly and treat base classes as annotations. var b = Eval.GetTypeFromAnnotation(a.Expression); if (b != null) { var t = b.GetPythonType(); bases.Add(t); t.AddReference(Eval.GetLocationOfName(a.Expression)); } } _class.SetBases(bases); // Declare __class__ variable in the scope. Eval.DeclareVariable("__class__", _class, VariableSource.Declaration); ProcessClassBody(); } }
private PythonClassType CreateClass(ClassDefinition cd) { PythonType declaringType = null; if (!(cd.Parent is PythonAst)) { if (!_typeMap.TryGetValue(cd.Parent, out declaringType)) { // we can get into this situation if parent is defined twice and we preserve // only one of them. // for example, code has function definition with exact same signature // and class is defined under one of that function return(null); } } var cls = new PythonClassType(cd, declaringType, _eval.GetLocationOfName(cd), _eval.SuppressBuiltinLookup ? BuiltinTypeId.Unknown : BuiltinTypeId.Type); _typeMap[cd] = cls; declaringType?.AddMember(cls.Name, cls, overwrite: true); return(cls); }