public void Compile(XamlIlDocument doc, IXamlIlType contextType, IXamlIlMethodBuilder populateMethod, IXamlIlMethodBuilder buildMethod, IXamlIlTypeBuilder namespaceInfoBuilder, Func <string, IXamlIlType, IXamlIlTypeBuilder> createClosure, string baseUri, IFileSource fileSource) { var rootGrp = (XamlIlValueWithManipulationNode)doc.Root; var staticProviders = new List <IXamlIlField>(); if (namespaceInfoBuilder != null) { staticProviders.Add( XamlIlNamespaceInfoHelper.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc)); } var context = new XamlIlContext(contextType, rootGrp.Type.GetClrType(), _configuration.TypeMappings, baseUri, staticProviders); CompilePopulate(fileSource, rootGrp.Manipulation, createClosure, populateMethod.Generator, context); if (buildMethod != null) { CompileBuild(fileSource, rootGrp.Value, null, buildMethod.Generator, context, populateMethod); } namespaceInfoBuilder?.CreateType(); }
public XamlIlEmitContext(XamlIlTransformerConfiguration configuration, XamlIlContext runtimeContext, IXamlIlLocal contextLocal, IEnumerable <object> emitters) { _emitters = emitters.ToList(); Configuration = configuration; RuntimeContext = runtimeContext; ContextLocal = contextLocal; }
public XamlIlEmitContext(IXamlIlEmitter emitter, XamlIlTransformerConfiguration configuration, XamlIlContext runtimeContext, IXamlIlLocal contextLocal, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IFileSource file, IEnumerable <object> emitters) { File = file; Emitter = emitter; Emitters = emitters.ToList(); Configuration = configuration; RuntimeContext = runtimeContext; ContextLocal = contextLocal; CreateSubType = createSubType; }
/// <summary> /// /// T Build(IServiceProvider sp); /// </summary> XamlIlEmitContext InitCodeGen(Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IXamlIlEmitter codeGen, XamlIlContext context, bool needContextLocal) { IXamlIlLocal contextLocal = null; if (needContextLocal) { contextLocal = codeGen.DefineLocal(context.ContextType); codeGen .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Newobj, context.Constructor) .Emit(OpCodes.Stloc, contextLocal); } var emitContext = new XamlIlEmitContext(codeGen, _configuration, context, contextLocal, createSubType, Emitters); return(emitContext); }
void CompileBuild(IXamlIlAstValueNode rootInstance, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IXamlIlEmitter codeGen, XamlIlContext context, IXamlIlMethod compiledPopulate) { var needContextLocal = !(rootInstance is XamlIlAstNewClrObjectNode newObj && newObj.Arguments.Count == 0); var emitContext = InitCodeGen(createSubType, codeGen, context, needContextLocal); var rv = codeGen.DefineLocal(rootInstance.Type.GetClrType()); emitContext.Emit(rootInstance, codeGen, rootInstance.Type.GetClrType()); codeGen .Emit(OpCodes.Stloc, rv) .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Ldloc, rv) .Emit(OpCodes.Call, compiledPopulate) .Emit(OpCodes.Ldloc, rv) .Emit(OpCodes.Ret); }
XamlIlEmitContext InitCodeGen( IFileSource file, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IXamlIlEmitter codeGen, XamlIlContext context, bool needContextLocal) { IXamlIlLocal contextLocal = null; if (needContextLocal) { contextLocal = codeGen.DefineLocal(context.ContextType); // Pass IService provider as the first argument to context factory codeGen .Emit(OpCodes.Ldarg_0); context.Factory(codeGen); codeGen.Emit(OpCodes.Stloc, contextLocal); } var emitContext = new XamlIlEmitContext(codeGen, _configuration, context, contextLocal, createSubType, file, Emitters); return(emitContext); }
public void Compile(XamlIlDocument doc, IXamlIlTypeBuilder typeBuilder, string populateMethodName, string createMethodName, string contextClassName, string namespaceInfoClassName, string baseUri) { var rootGrp = (XamlIlValueWithManipulationNode)doc.Root; var staticProviders = new List <IXamlIlField>(); IXamlIlTypeBuilder namespaceInfoBuilder = null; if (_configuration.TypeMappings.XmlNamespaceInfoProvider != null) { namespaceInfoBuilder = typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object, namespaceInfoClassName, false); staticProviders.Add( XamlIlNamespaceInfoHelper.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc)); } var contextBuilder = typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object, contextClassName, false); var contextType = XamlIlContext.GenerateContextClass(contextBuilder, _configuration.TypeSystem, _configuration.TypeMappings, rootGrp.Type.GetClrType(), staticProviders, baseUri); var populateMethod = typeBuilder.DefineMethod(_configuration.WellKnownTypes.Void, new[] { _configuration.TypeMappings.ServiceProvider, rootGrp.Type.GetClrType() }, populateMethodName, true, true, false); IXamlIlTypeBuilder CreateSubType(string name, IXamlIlType baseType) => typeBuilder.DefineSubType(baseType, name, false); CompilePopulate(rootGrp.Manipulation, CreateSubType, populateMethod.Generator, contextType); var createMethod = typeBuilder.DefineMethod(rootGrp.Type.GetClrType(), new[] { _configuration.TypeMappings.ServiceProvider }, createMethodName, true, true, false); CompileBuild(rootGrp.Value, CreateSubType, createMethod.Generator, contextType, populateMethod); namespaceInfoBuilder?.CreateType(); contextType.CreateAllTypes(); }
/// <summary> /// populate = true: /// void Populate(IServiceProvider sp, T target); /// populate = false /// T Build(IServiceProvider sp); /// </summary> public void Compile(IXamlIlAstNode root, IXamlIlCodeGen codeGen, XamlIlContext context, bool populate) { var contextLocal = codeGen.Generator.DefineLocal(context.ContextType); codeGen.Generator .Emit(OpCodes.Ldarg_0) .Emit(OpCodes.Newobj, context.Constructor) .Emit(OpCodes.Stloc, contextLocal); var rootGrp = (XamlIlValueWithManipulationNode)root; var emitContext = new XamlIlEmitContext(_configuration, context, contextLocal, Emitters); if (populate) { codeGen.Generator .Emit(OpCodes.Ldloc, contextLocal) .Emit(OpCodes.Ldarg_1) .Emit(OpCodes.Stfld, context.RootObjectField) .Emit(OpCodes.Ldarg_1); emitContext.Emit(rootGrp.Manipulation, codeGen, null); codeGen.Generator.Emit(OpCodes.Ret); } else { codeGen.Generator.Emit(OpCodes.Ldloc, contextLocal); emitContext.Emit(rootGrp.Value, codeGen, rootGrp.Value.Type.GetClrType()); codeGen.Generator .Emit(OpCodes.Stfld, context.RootObjectField); codeGen.Generator .Emit(OpCodes.Ldloc, contextLocal) .Emit(OpCodes.Ldfld, context.RootObjectField) .Emit(OpCodes.Dup); emitContext.Emit(rootGrp.Manipulation, codeGen, null); codeGen.Generator.Emit(OpCodes.Ret); } }
/// <summary> /// void Populate(IServiceProvider sp, T target); /// </summary> void CompilePopulate(IXamlIlAstManipulationNode manipulation, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IXamlIlEmitter codeGen, XamlIlContext context) { var emitContext = InitCodeGen(createSubType, codeGen, context, true); codeGen .Emit(OpCodes.Ldloc, emitContext.ContextLocal) .Emit(OpCodes.Ldarg_1) .Emit(OpCodes.Stfld, context.RootObjectField) .Emit(OpCodes.Ldarg_1); emitContext.Emit(manipulation, codeGen, null); codeGen.Emit(OpCodes.Ret); }
/// <summary> /// void Populate(IServiceProvider sp, T target); /// </summary> void CompilePopulate(IFileSource fileSource, IXamlIlAstManipulationNode manipulation, Func <string, IXamlIlType, IXamlIlTypeBuilder> createSubType, IXamlIlEmitter codeGen, XamlIlContext context) { // Uncomment to inspect generated IL in debugger //codeGen = new RecordingIlEmitter(codeGen); var emitContext = InitCodeGen(fileSource, createSubType, codeGen, context, true); codeGen .Emit(OpCodes.Ldloc, emitContext.ContextLocal) .Emit(OpCodes.Ldarg_1) .Emit(OpCodes.Stfld, context.RootObjectField) .Emit(OpCodes.Ldloc, emitContext.ContextLocal) .Emit(OpCodes.Ldarg_1) .Emit(OpCodes.Stfld, context.IntermediateRootObjectField) .Emit(OpCodes.Ldarg_1); emitContext.Emit(manipulation, codeGen, null); codeGen.Emit(OpCodes.Ret); }