Exemple #1
0
        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;
 }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        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);
            }
        }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        /// <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);
        }