internal override MSAst.Expression Transform(AstGenerator ag) { string className = _name; AstGenerator classGen = new AstGenerator(ag, className, false, "class " + className); classGen.Parameter(_parentContextParam); // we always need to create a nested context for class defs classGen.CreateNestedContext(); List<MSAst.Expression> init = new List<MSAst.Expression>(); classGen.AddHiddenVariable(ArrayGlobalAllocator._globalContext); init.Add(Ast.Assign(ArrayGlobalAllocator._globalContext, Ast.Call(typeof(PythonOps).GetMethod("GetGlobalContext"), _parentContextParam))); init.AddRange(classGen.Globals.PrepareScope(classGen)); CreateVariables(classGen, _parentContextParam, init, true, false); List<MSAst.Expression> statements = new List<MSAst.Expression>(); // Create the body MSAst.Expression bodyStmt = classGen.Transform(_body); // __module__ = __name__ MSAst.Expression modStmt = GlobalAllocator.Assign( classGen.Globals.GetVariable(classGen, _modVariable), classGen.Globals.GetVariable(classGen, _modNameVariable)); string doc = classGen.GetDocumentation(_body); if (doc != null) { statements.Add( GlobalAllocator.Assign( classGen.Globals.GetVariable(classGen, _docVariable), AstUtils.Constant(doc) ) ); } FunctionCode funcCodeObj = new FunctionCode( ag.PyContext, null, null, Name, ag.GetDocumentation(_body), ArrayUtils.EmptyStrings, FunctionAttributes.None, Span, ag.Context.SourceUnit.Path, ag.EmitDebugSymbols, ag.ShouldInterpret, FreeVariables, GlobalVariables, CellVariables, AppendVariables(new List<string>()), Variables == null ? 0 : Variables.Count, classGen.LoopLocationsNoCreate, classGen.HandlerLocationsNoCreate ); MSAst.Expression funcCode = classGen.Globals.GetConstant(funcCodeObj); classGen.FuncCodeExpr = funcCode; if (_body.CanThrow && ag.PyContext.PythonOptions.Frames) { bodyStmt = AstGenerator.AddFrame(classGen.LocalContext, funcCode, bodyStmt); classGen.AddHiddenVariable(AstGenerator._functionStack); } bodyStmt = classGen.WrapScopeStatements( Ast.Block( statements.Count == 0 ? AstGenerator.EmptyBlock : Ast.Block(new ReadOnlyCollection<MSAst.Expression>(statements)), modStmt, bodyStmt, classGen.LocalContext // return value ) ); var lambda = Ast.Lambda<Func<CodeContext, CodeContext>>( classGen.MakeBody(_parentContextParam, init.ToArray(), bodyStmt), classGen.Name + "$" + _classId++, classGen.Parameters ); funcCodeObj.Code = lambda; MSAst.Expression classDef = Ast.Call( AstGenerator.GetHelperMethod("MakeClass"), ag.EmitDebugSymbols ? (MSAst.Expression)lambda : Ast.Convert(funcCode, typeof(object)), ag.LocalContext, AstUtils.Constant(_name), Ast.NewArrayInit( typeof(object), ag.TransformAndConvert(_bases, typeof(object)) ), AstUtils.Constant(FindSelfNames()) ); classDef = ag.AddDecorators(classDef, _decorators); return ag.AddDebugInfoAndVoid(GlobalAllocator.Assign(ag.Globals.GetVariable(ag, _variable), classDef), new SourceSpan(Start, Header)); }
internal MSAst.Expression Transform(AstGenerator inner, bool needsWrapperMethod, bool needsLocalsDictionary, List<MSAst.Expression> init) { string name = SymbolTable.IdToString(Name); if (_variable.AccessedInNestedScope || needsLocalsDictionary) { ClosureExpression closureVar; if (needsWrapperMethod) { closureVar = inner.LiftedVariable(Variable, name, _variable.AccessedInNestedScope); } else { closureVar = inner.LiftedParameter(Variable, name); } inner.SetLocalLiftedVariable(_variable, closureVar); init.Add(closureVar.Create()); return closureVar; } else { MSAst.Expression parameter; if (needsWrapperMethod) { parameter = inner.Variable(typeof(object), name); } else { parameter = inner.Parameter(typeof(object), name); } inner.Globals.SetParameter(_variable, parameter); return parameter; } }
internal MSAst.Expression Transform(AstGenerator inner, bool needsWrapperMethod) { MSAst.ParameterExpression parameter; string name = SymbolTable.IdToString(Name); if (_variable.AccessedInNestedScope) { if (needsWrapperMethod) { parameter = inner.ClosedOverVariable(typeof(object), name); } else { parameter = inner.ClosedOverParameter(typeof(object), name); } } else { if (needsWrapperMethod) { parameter = inner.Variable(typeof(object), name); } else { parameter = inner.Parameter(typeof(object), name); } } inner.Globals.SetParameter(_variable, parameter); return parameter; }
private void TransformParameters(AstGenerator outer, AstGenerator inner, List<MSAst.Expression> defaults, List<MSAst.Expression> names, bool needsWrapperMethod, List<MSAst.Expression> init) { inner.Parameter(_functionParam); if (needsWrapperMethod) { // define a single parameter which takes all arguments inner.Parameter(typeof(object[]), "allArgs"); } for (int i = 0; i < _parameters.Length; i++) { // Create the parameter in the inner code block Parameter p = _parameters[i]; p.Transform(inner, needsWrapperMethod, NeedsLocalsDictionary, init); // Transform the default value if (p.DefaultValue != null) { defaults.Add( outer.TransformAndConvert(p.DefaultValue, typeof(object)) ); } names.Add( AstUtils.Constant( SymbolTable.IdToString(p.Name) ) ); } }
internal override MSAst.Expression Transform(AstGenerator ag) { string className = SymbolTable.IdToString(_name); AstGenerator classGen = new AstGenerator(ag, className, false, "class " + className); classGen.Parameter(_parentContextParam); // we always need to create a nested context for class defs classGen.CreateNestedContext(); List<MSAst.Expression> init = new List<MSAst.Expression>(); classGen.AddHiddenVariable(ArrayGlobalAllocator._globalContext); init.Add(Ast.Assign(ArrayGlobalAllocator._globalContext, Ast.Call(typeof(PythonOps).GetMethod("GetGlobalContext"), _parentContextParam))); init.AddRange(classGen.Globals.PrepareScope(classGen)); CreateVariables(classGen, _parentContextParam, init, true, NeedsLocalsDictionary); List<MSAst.Expression> statements = new List<MSAst.Expression>(); // Create the body MSAst.Expression bodyStmt = classGen.Transform(_body); // __module__ = __name__ MSAst.Expression modStmt = classGen.Globals.Assign( classGen.Globals.GetVariable(classGen, _modVariable), classGen.Globals.GetVariable(classGen, _modNameVariable)); string doc = classGen.GetDocumentation(_body); if (doc != null) { statements.Add( classGen.Globals.Assign( classGen.Globals.GetVariable(classGen, _docVariable), AstUtils.Constant(doc) ) ); } bodyStmt = classGen.WrapScopeStatements( Ast.Block( statements.Count == 0 ? AstGenerator.EmptyBlock : Ast.Block(new ReadOnlyCollection<MSAst.Expression>(statements)), modStmt, bodyStmt, classGen.LocalContext // return value ) ); var lambda = Ast.Lambda<Func<CodeContext, CodeContext>>( classGen.MakeBody(_parentContextParam, init.ToArray(), bodyStmt, false), classGen.Name + "$" + _classId++, classGen.Parameters ); MSAst.Expression classDef = Ast.Call( AstGenerator.GetHelperMethod("MakeClass"), ag.EmitDebugSymbols ? (MSAst.Expression)lambda : (MSAst.Expression)Ast.Constant(new LazyCode<Func<CodeContext, CodeContext>>(lambda, ag.ShouldInterpret), typeof(object)), ag.LocalContext, AstUtils.Constant(SymbolTable.IdToString(_name)), Ast.NewArrayInit( typeof(object), ag.TransformAndConvert(_bases, typeof(object)) ), AstUtils.Constant(FindSelfNames()) ); classDef = ag.AddDecorators(classDef, _decorators); return ag.AddDebugInfo(ag.Globals.Assign(ag.Globals.GetVariable(ag, _variable), classDef), new SourceSpan(Start, Header)); }