internal void EmitDefinition(CodeGenerator/*!*/ codeGenerator) { if (type.IsComplete) { Debug.Assert(type.IsComplete, "Incomplete types should be converted to evals."); Debug.Assert(type.RealTypeBuilder != null, "A class declared during compilation should have a type builder."); attributes.Emit(codeGenerator, this); typeSignature.Emit(codeGenerator); codeGenerator.EnterTypeDeclaration(type); foreach (TypeMemberDecl member_decl in members) { member_decl.EnterCodegenerator(codeGenerator); member_decl.Emit(codeGenerator); member_decl.LeaveCodegenerator(codeGenerator); } // emit stubs for implemented methods & properties that were not declared by this type: codeGenerator.EmitGhostStubs(type); codeGenerator.LeaveTypeDeclaration(); } else { Debug.Assert(this.typeDefinitionCode != null); // LOAD DynamicCode.Eval(<code>, context, definedVariables, self, includer, source, line, column, evalId) // wrap Eval into static method MethodBuilder method = codeGenerator.IL.TypeBuilder.DefineMethod( string.Format("{0}{1}", ScriptModule.DeclareHelperNane, type.FullName), MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName, Types.Void, Types.ScriptContext); var il = new ILEmitter(method); codeGenerator.EnterLambdaDeclaration(il, false, LiteralPlace.Null, new IndexedPlace(PlaceHolder.Argument, 0), LiteralPlace.Null, LiteralPlace.Null); if (true) { codeGenerator.EmitEval( EvalKinds.SyntheticEval, new StringLiteral(position, this.typeDefinitionCode, AccessType.Read), position, (this.Namespace != null) ? this.Namespace.QualifiedName : (QualifiedName?)null, this.validAliases); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ret); } codeGenerator.LeaveFunctionDeclaration(); // il = codeGenerator.IL; type.IncompleteClassDeclareMethodInfo = method; type.IncompleteClassDeclarationId = String.Format("{0}${1}:{2}:{3}", type.FullName, unchecked((uint)codeGenerator.SourceUnit.SourceFile.ToString().GetHashCode()), position.FirstLine, position.FirstColumn); // sequence point here codeGenerator.MarkSequencePoint(position.FirstLine, position.FirstColumn, position.LastLine, position.LastColumn + 2); if (type.Declaration.IsConditional) { // CALL <Declare>.<FullName>(<context>) codeGenerator.EmitLoadScriptContext(); il.Emit(OpCodes.Call, method); } else { // if (!<context>.IncompleteTypeDeclared(<id>)) // CALL <Declare>.<FullName>(<context>) var end_if = il.DefineLabel(); codeGenerator.EmitLoadScriptContext(); il.Emit(OpCodes.Ldstr, type.IncompleteClassDeclarationId); il.Emit(OpCodes.Call, Methods.ScriptContext.IncompleteTypeDeclared); il.Emit(OpCodes.Brtrue, end_if); if (true) { codeGenerator.EmitLoadScriptContext(); il.Emit(OpCodes.Call, type.IncompleteClassDeclareMethodInfo); } il.MarkLabel(end_if); il.ForgetLabel(end_if); } } }