private Microsoft.Scripting.Ast.LightExpression<Func<CodeContext, CodeContext>> MakeClassBody() {
// we always need to create a nested context for class defs
var init = new List<MSAst.Expression>();
var locals = new ReadOnlyCollectionBuilder<MSAst.ParameterExpression>();
locals.Add(LocalCodeContextVariable);
locals.Add(PythonAst._globalContext);
init.Add(Ast.Assign(PythonAst._globalContext, new GetGlobalContextExpression(_parentContextParam)));
GlobalParent.PrepareScope(locals, init);
CreateVariables(locals, init);
var createLocal = CreateLocalContext(_parentContextParam);
init.Add(Ast.Assign(LocalCodeContextVariable, createLocal));
List<MSAst.Expression> statements = new List<MSAst.Expression>();
// Create the body
MSAst.Expression bodyStmt = _body;
// __module__ = __name__
MSAst.Expression modStmt = AssignValue(GetVariableExpression(_modVariable), GetVariableExpression(_modNameVariable));
string doc = GetDocumentation(_body);
if (doc != null) {
statements.Add(
AssignValue(
GetVariableExpression(_docVariable),
AstUtils.Constant(doc)
)
);
}
if (_body.CanThrow && GlobalParent.PyContext.PythonOptions.Frames) {
bodyStmt = AddFrame(LocalContext, FuncCodeExpr, bodyStmt);
locals.Add(FunctionStackVariable);
}
bodyStmt = WrapScopeStatements(
Ast.Block(
Ast.Block(init),
statements.Count == 0 ?
EmptyBlock :
Ast.Block(new ReadOnlyCollection<MSAst.Expression>(statements)),
modStmt,
bodyStmt,
LocalContext
),
_body.CanThrow
);
var lambda = AstUtils.LightLambda<Func<CodeContext, CodeContext>>(
typeof(CodeContext),
Ast.Block(
locals,
bodyStmt
),
Name + "$" + Interlocked.Increment(ref _classId),
new[] { _parentContextParam }
);
return lambda;
}