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 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); }
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(); } }
protected override void EnsureContent(ClassModel cm) { var bases = CreateBases(cm, ModuleFactory, GlobalScope); _cls.SetBases(bases); if (cm.GenericParameterValues.Length > 0) { _cls.StoreGenericParameters( _cls, _cls.GenericParameters.Keys.ToArray(), cm.GenericParameterValues.ToDictionary( k => _cls.GenericParameters.Keys.First(x => x == k.Name), v => ModuleFactory.ConstructType(v.Type) ) ); } foreach (var model in GetMemberModels(cm)) { _cls.AddMember(model.Name, MemberFactory.CreateMember(model, ModuleFactory, GlobalScope, _cls), false); } _cls.AddMember("__class__", _cls, true); }