public List <RecordingIlEmitter.RecordedInstruction> Compile(
            XamlDocument doc,
            IXamlType contextType,
            IXamlMethodBuilder <TBackendEmitter> populateMethod,
            IXamlMethodBuilder <TBackendEmitter> buildMethod,
            IXamlTypeBuilder <TBackendEmitter> namespaceInfoBuilder,
            Func <string, IXamlType, IXamlTypeBuilder <TBackendEmitter> > createClosure,
            string baseUri,
            IFileSource fileSource)
        {
            var rootGrp  = (XamlValueWithManipulationNode)doc.Root;
            var rootType = rootGrp.Type.GetClrType();
            var context  = CreateRuntimeContext(doc, contextType, namespaceInfoBuilder, baseUri, rootType);

            var populateInstructions = CompilePopulate(
                fileSource,
                rootGrp.Manipulation,
                createClosure,
                populateMethod.Generator,
                context);

            if (buildMethod != null)
            {
                CompileBuild(fileSource, rootGrp.Value, null, buildMethod.Generator, context, populateMethod);
            }

            namespaceInfoBuilder?.CreateType();

            return(populateInstructions);
        }
 public AvaloniaXamlIlCompiler(TransformerConfiguration configuration,
                               XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings,
                               IXamlTypeBuilder <IXamlILEmitter> contextTypeBuilder)
     : this(configuration, emitMappings)
 {
     _contextType = CreateContextType(contextTypeBuilder);
 }
Beispiel #3
0
        IXamlType EmitTypeDescriptorContextStub(IXamlTypeSystem typeSystem, IXamlTypeBuilder <IXamlILEmitter> builder,
                                                XamlLanguageTypeMappings mappings)
        {
            if (mappings.TypeDescriptorContext == null)
            {
                return(null);
            }
            var tdc       = mappings.TypeDescriptorContext;
            var tdcPrefix = tdc.Namespace + "." + tdc.Name + ".";

            builder.AddInterfaceImplementation(mappings.TypeDescriptorContext);
            void PropertyStub(string name) => ImplementInterfacePropertyGetter(builder, tdc, name).Generator.Ldnull().Ret();

            PropertyStub("Container");
            PropertyStub("Instance");
            PropertyStub("PropertyDescriptor");

            void MethodStub(string name)
            {
                var original = tdc.FindMethod(m => m.Name == name);

                builder.DefineMethod(original.ReturnType, original.Parameters, tdcPrefix + name,
                                     false, false, true,
                                     original)
                .Generator
                .Emit(OpCodes.Newobj,
                      typeSystem.FindType("System.NotSupportedException").FindConstructor(new List <IXamlType>()))
                .Emit(OpCodes.Throw);
            }

            MethodStub("OnComponentChanging");
            MethodStub("OnComponentChanged");

            return(mappings.TypeDescriptorContext);
        }
        /// <summary>
        /// T Build(IServiceProvider sp);
        /// </summary>
        public IXamlMethodBuilder <TBackendEmitter> DefineBuildMethod(IXamlTypeBuilder <TBackendEmitter> typeBuilder,
                                                                      XamlDocument doc,
                                                                      string name, bool isPublic)
        {
            var rootGrp = (XamlValueWithManipulationNode)doc.Root;

            return(typeBuilder.DefineMethod(rootGrp.Type.GetClrType(),
                                            new[] { _configuration.TypeMappings.ServiceProvider }, name, isPublic, true, false));
        }
Beispiel #5
0
        private IXamlMethodBuilder <IXamlILEmitter> ImplementInterfacePropertyGetter(IXamlTypeBuilder <IXamlILEmitter> builder,
                                                                                     IXamlType type, string name)
        {
            var prefix         = type.Namespace + "." + type.Name + ".";
            var originalGetter = type.FindMethod(m => m.Name == "get_" + name);
            var gen            = builder.DefineMethod(originalGetter.ReturnType, new IXamlType[0],
                                                      prefix + "get_" + name, false, false,
                                                      true, originalGetter);

            builder.DefineProperty(originalGetter.ReturnType, prefix + name, null, gen);
            return(gen);
        }
Beispiel #6
0
        private void EmitPushPopParent(IXamlTypeBuilder <IXamlILEmitter> builder, IXamlTypeSystem ts)
        {
            var @void          = ts.GetType("System.Void");
            var so             = ts.GetType("System.Object");
            var objectListType = ts.GetType("System.Collections.Generic.List`1")
                                 .MakeGenericType(new[] { so });

            var pushParentGenerator =
                builder.DefineMethod(@void, new[] { so }, XamlRuntimeContextDefintion.PushParentMethodName, true, false, false)
                .Generator;

            pushParentGenerator.LdThisFld(ParentListField)
            .Ldarg(1)
            .EmitCall(objectListType.FindMethod("Add", @void,
                                                false, so));

            if (PropertyTargetObject != null)
            {
                pushParentGenerator.Ldarg_0()
                .Ldarg(1)
                .Stfld(PropertyTargetObject)
                .Ret();
            }

            var pop = builder.DefineMethod(@void, new IXamlType[0], XamlRuntimeContextDefintion.PopParentMethodName, true, false, false)
                      .Generator;

            var idx = pop.DefineLocal(ts.GetType("System.Int32"));

            pop
            // var idx = _parents.Count - 1;
            .LdThisFld(ParentListField)
            .EmitCall(objectListType.FindMethod(m => m.Name == "get_Count"))
            .Ldc_I4(1).Emit(OpCodes.Sub).Stloc(idx);
            // this.PropertyTargetObject = _parents[idx];
            if (PropertyTargetObject != null)
            {
                pop
                .Ldarg_0()
                .LdThisFld(ParentListField)
                .Ldloc(idx)
                .EmitCall(objectListType.FindMethod(m => m.Name == "get_Item"))
                .Stfld(PropertyTargetObject);
            }
            // _parents.RemoveAt(idx);
            pop
            .LdThisFld(ParentListField)
            .Ldloc(idx).EmitCall(objectListType.FindMethod(m => m.Name == "RemoveAt"))
            .Ret();
        }
Beispiel #7
0
        private static void EmitNameScopeField(XamlLanguageTypeMappings mappings,
                                               IXamlTypeSystem typeSystem,
                                               IXamlTypeBuilder <IXamlILEmitter> typebuilder, IXamlILEmitter constructor)
        {
            var nameScopeType = typeSystem.FindType("Avalonia.Controls.INameScope");
            var field         = typebuilder.DefineField(nameScopeType,
                                                        ContextNameScopeFieldName, true, false);

            constructor
            .Ldarg_0()
            .Ldarg(1)
            .Ldtype(nameScopeType)
            .EmitCall(mappings.ServiceProvider.GetMethod(new FindMethodMethodSignature("GetService",
                                                                                       typeSystem.FindType("System.Object"), typeSystem.FindType("System.Type"))))
            .Stfld(field);
        }
Beispiel #8
0
        XamlDocument Compile(IXamlTypeBuilder <IXamlILEmitter> builder, IXamlType context, string xaml)
        {
            var parsed   = XDocumentXamlParser.Parse(xaml);
            var compiler = new XamlILCompiler(
                Configuration,
                new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult>(),
                true)
            {
                EnableIlVerification = true
            };

            compiler.Transform(parsed);
            compiler.Compile(parsed, builder, context, "Populate", "Build",
                             "XamlNamespaceInfo",
                             "http://example.com/", null);
            return(parsed);
        }
Beispiel #9
0
        public void Compile(XamlDocument doc, IXamlTypeBuilder <TBackendEmitter> typeBuilder, IXamlType contextType,
                            string populateMethodName, string createMethodName, string namespaceInfoClassName,
                            string baseUri, IFileSource fileSource)
        {
            var rootGrp = (XamlValueWithManipulationNode)doc.Root;

            Compile(doc, contextType,
                    DefinePopulateMethod(typeBuilder, doc, populateMethodName, true),
                    createMethodName == null ?
                    null :
                    DefineBuildMethod(typeBuilder, doc, createMethodName, true),
                    _configuration.TypeMappings.XmlNamespaceInfoProvider == null ?
                    null :
                    typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object,
                                              namespaceInfoClassName, false),
                    (name, bt) => typeBuilder.DefineSubType(bt, name, false),
                    baseUri, fileSource);
        }
Beispiel #10
0
        public void Compile(XamlDocument doc, IXamlType contextType,
                            IXamlMethodBuilder <TBackendEmitter> populateMethod, IXamlMethodBuilder <TBackendEmitter> buildMethod,
                            IXamlTypeBuilder <TBackendEmitter> namespaceInfoBuilder,
                            Func <string, IXamlType, IXamlTypeBuilder <TBackendEmitter> > createClosure,
                            Func <string, IXamlType, IEnumerable <IXamlType>, IXamlTypeBuilder <TBackendEmitter> > createDelegateType,
                            string baseUri, IFileSource fileSource)
        {
            var rootGrp  = (XamlValueWithManipulationNode)doc.Root;
            var rootType = rootGrp.Type.GetClrType();
            var context  = CreateRuntimeContext(doc, contextType, namespaceInfoBuilder, baseUri, rootType);

            CompilePopulate(fileSource, rootGrp.Manipulation, createClosure, createDelegateType, populateMethod.Generator, context);

            if (buildMethod != null)
            {
                CompileBuild(fileSource, rootGrp.Value, null, createDelegateType, buildMethod.Generator, context, populateMethod);
            }

            namespaceInfoBuilder?.CreateType();
        }
 public List <RecordingIlEmitter.RecordedInstruction> Compile(
     XamlDocument doc,
     IXamlTypeBuilder <TBackendEmitter> typeBuilder,
     IXamlType contextType,
     string populateMethodName,
     string createMethodName,
     string namespaceInfoClassName,
     string baseUri,
     IFileSource fileSource)
 {
     return(Compile(
                doc,
                contextType,
                DefinePopulateMethod(typeBuilder, doc, populateMethodName, true),
                createMethodName == null
             ? null
             : DefineBuildMethod(typeBuilder, doc, createMethodName, true),
                _configuration.TypeMappings.XmlNamespaceInfoProvider == null
             ? null
             : typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object, namespaceInfoClassName, true),
                (name, bt) => typeBuilder.DefineSubType(bt, name, false),
                baseUri,
                fileSource));
 }
 protected abstract XamlRuntimeContext <TBackendEmitter, TEmitResult> CreateRuntimeContext(
     XamlDocument doc,
     IXamlType contextType,
     IXamlTypeBuilder <TBackendEmitter> namespaceInfoBuilder,
     string baseUri,
     IXamlType rootType);
Beispiel #13
0
 public static IXamlType GenerateContextClass(IXamlTypeBuilder <IXamlILEmitter> builder,
                                              IXamlTypeSystem typeSystem, XamlLanguageTypeMappings mappings,
                                              XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings)
 {
     return(new XamlILContextDefinition(builder, typeSystem, mappings, emitMappings).ContextType);
 }
Beispiel #14
0
        private static void EmitNameScopeField(XamlLanguageTypeMappings xamlLanguage, CecilTypeSystem typeSystem, IXamlTypeBuilder <IXamlILEmitter> typeBuilder, IXamlILEmitter constructor)
        {
            var nameScopeType = typeSystem.FindType("Robust.Client.UserInterface.XAML.NameScope");
            var field         = typeBuilder.DefineField(nameScopeType,
                                                        ContextNameScopeFieldName, true, false);

            constructor
            .Ldarg_0()
            .Newobj(nameScopeType.GetConstructor())
            .Stfld(field);
        }
 public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlTypeBuilder <IXamlILEmitter> indexerClosureType)
 {
     _indexerClosureTypeBuilder = indexerClosureType;
 }
Beispiel #16
0
        private XamlILContextDefinition(IXamlTypeBuilder <IXamlILEmitter> parentBuilder,
                                        IXamlTypeSystem typeSystem, XamlLanguageTypeMappings mappings,
                                        XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings)
        {
            var so      = typeSystem.GetType("System.Object");
            var builder = parentBuilder.DefineSubType(so, "Context", true);

            builder.DefineGenericParameters(new[]
            {
                new KeyValuePair <string, XamlGenericParameterConstraint>("TTarget",
                                                                          new XamlGenericParameterConstraint
                {
                    IsClass = true
                })
            });
            var rootObjectField             = builder.DefineField(builder.GenericParameters[0], "RootObject", true, false);
            var intermediateRootObjectField = builder.DefineField(so, XamlRuntimeContextDefintion.IntermediateRootObjectFieldName, true, false);

            _parentServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_sp", false, false);
            if (mappings.InnerServiceProviderFactoryMethod != null)
            {
                _innerServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_innerSp", false, false);
            }

            var staticProvidersField = builder.DefineField(typeSystem.GetType("System.Object").MakeArrayType(1),
                                                           "_staticProviders", false, false);


            var systemType   = typeSystem.GetType("System.Type");
            var systemUri    = typeSystem.GetType("System.Uri");
            var systemString = typeSystem.GetType("System.String");
            var getServiceInterfaceMethod = mappings.ServiceProvider.FindMethod("GetService", so, false, systemType);

            var ownServices   = new List <IXamlType>();
            var ctorCallbacks = new List <Action <IXamlILEmitter> >();

            if (mappings.RootObjectProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.RootObjectProvider);
                var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, XamlRuntimeContextDefintion.RootObjectFieldName)
                              .Generator;
                var tryParent          = rootGen.DefineLabel();
                var fail               = rootGen.DefineLabel();
                var parentRootProvider = rootGen.DefineLocal(mappings.RootObjectProvider);
                rootGen
                // if(RootObject!=null) return RootObject;
                .LdThisFld(rootObjectField)
                .Box(rootObjectField.FieldType)
                .Brfalse(tryParent)
                .LdThisFld(rootObjectField)
                .Box(rootObjectField.FieldType)
                .Ret()
                // if(_sp == null) goto fail;
                .MarkLabel(tryParent)
                .LdThisFld(_parentServiceProviderField)
                .Brfalse(fail)
                // parentProv =  (IRootObjectProvider)_sp.GetService(typeof(IRootObjectProvider));
                .LdThisFld(_parentServiceProviderField)
                .Ldtype(mappings.RootObjectProvider)
                .EmitCall(getServiceInterfaceMethod)
                .Castclass(mappings.RootObjectProvider)
                .Stloc(parentRootProvider)
                // if(parentProv == null) goto fail;
                .Ldloc(parentRootProvider)
                .Brfalse(fail)
                // return parentProv.Root;
                .Ldloc(parentRootProvider)
                .EmitCall(mappings.RootObjectProvider.FindMethod(m => m.Name == "get_RootObject"))
                .Ret()
                // fail:
                .MarkLabel(fail)
                .Ldnull()
                .Ret();

                if (mappings.RootObjectProviderIntermediateRootPropertyName != null)
                {
                    ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, mappings.RootObjectProviderIntermediateRootPropertyName)
                    .Generator
                    .LdThisFld(intermediateRootObjectField)
                    .Ret();
                }

                ownServices.Add(mappings.RootObjectProvider);
            }

            if (mappings.ParentStackProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.ParentStackProvider);
                var objectListType = typeSystem.GetType("System.Collections.Generic.List`1")
                                     .MakeGenericType(new[] { typeSystem.GetType("System.Object") });
                ParentListField = builder.DefineField(objectListType, XamlRuntimeContextDefintion.ParentListFieldName, true, false);

                var enumerator = EmitParentEnumerable(typeSystem, parentBuilder, mappings);
                CreateCallbacks.Add(enumerator.createCallback);
                var parentStackEnumerableField = builder.DefineField(
                    typeSystem.GetType("System.Collections.Generic.IEnumerable`1").MakeGenericType(new[] { so }),
                    "_parentStackEnumerable", false, false);

                ImplementInterfacePropertyGetter(builder, mappings.ParentStackProvider, "Parents")
                .Generator.LdThisFld(parentStackEnumerableField).Ret();

                ctorCallbacks.Add(g => g
                                  .Emit(OpCodes.Ldarg_0)
                                  .Emit(OpCodes.Newobj, objectListType.FindConstructor(new List <IXamlType>()))
                                  .Emit(OpCodes.Stfld, ParentListField)
                                  .Emit(OpCodes.Ldarg_0)
                                  .LdThisFld(ParentListField)
                                  .LdThisFld(_parentServiceProviderField)
                                  .Emit(OpCodes.Newobj, enumerator.ctor)
                                  .Emit(OpCodes.Stfld, parentStackEnumerableField));
                ownServices.Add(mappings.ParentStackProvider);
            }

            ownServices.Add(EmitTypeDescriptorContextStub(typeSystem, builder, mappings));

            if (mappings.ProvideValueTarget != null)
            {
                builder.AddInterfaceImplementation(mappings.ProvideValueTarget);
                PropertyTargetObject   = builder.DefineField(so, XamlRuntimeContextDefintion.ProvideTargetObjectName, true, false);
                PropertyTargetProperty = builder.DefineField(so, XamlRuntimeContextDefintion.ProvideTargetPropertyName, true, false);
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetObject")
                .Generator.LdThisFld(PropertyTargetObject).Ret();
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetProperty")
                .Generator.LdThisFld(PropertyTargetProperty).Ret();
                ownServices.Add(mappings.ProvideValueTarget);
            }

            IXamlField baseUriField = null;

            if (mappings.UriContextProvider != null)
            {
                baseUriField = builder.DefineField(systemUri, "_baseUri", false, false);
                builder.AddInterfaceImplementation(mappings.UriContextProvider);
                var getter = builder.DefineMethod(systemUri, new IXamlType[0], "get_BaseUri", true, false, true);
                var setter = builder.DefineMethod(typeSystem.GetType("System.Void"), new[] { systemUri },
                                                  "set_BaseUri", true, false, true);

                getter.Generator
                .LdThisFld(baseUriField)
                .Ret();

                setter.Generator
                .Ldarg_0()
                .Ldarg(1)
                .Stfld(baseUriField)
                .Ret();
                builder.DefineProperty(systemUri, "BaseUri", setter, getter);


                ownServices.Add(mappings.UriContextProvider);
            }

            builder.AddInterfaceImplementation(mappings.ServiceProvider);
            var getServiceMethod = builder.DefineMethod(so,
                                                        new[] { systemType },
                                                        "GetService", true, false, true);

            ownServices = ownServices.Where(s => s != null).ToList();


            if (_innerServiceProviderField != null)
            {
                var next        = getServiceMethod.Generator.DefineLabel();
                var innerResult = getServiceMethod.Generator.DefineLocal(so);
                getServiceMethod.Generator
                //if(_inner == null) goto next;
                .LdThisFld(_innerServiceProviderField)
                .Brfalse(next)
                // var innerRes = _inner.GetService(type);
                .LdThisFld(_innerServiceProviderField)
                .Ldarg(1)
                .EmitCall(getServiceInterfaceMethod)
                .Stloc(innerResult)
                // if(innerRes == null) goto next;
                .Ldloc(innerResult)
                .Brfalse(next)
                // return innerRes
                .Ldloc(innerResult)
                .Ret()
                .MarkLabel(next);
            }
            var compare = systemType.FindMethod("Equals", typeSystem.GetType("System.Boolean"),
                                                false, systemType);
            var isAssignableFrom = systemType.FindMethod("IsAssignableFrom", typeSystem.GetType("System.Boolean"),
                                                         false, systemType);
            var fromHandle        = systemType.Methods.First(m => m.Name == "GetTypeFromHandle");
            var getTypeFromObject = so.Methods.First(m => m.Name == "GetType" && m.Parameters.Count == 0);

            if (ownServices.Count != 0)
            {
                for (var c = 0; c < ownServices.Count; c++)
                {
                    var next = getServiceMethod.Generator.DefineLabel();
                    getServiceMethod.Generator
                    .Emit(OpCodes.Ldtoken, ownServices[c])
                    .EmitCall(fromHandle)
                    .Emit(OpCodes.Ldarg_1)
                    .Emit(OpCodes.Callvirt, compare)
                    .Emit(OpCodes.Brfalse, next)
                    .Emit(OpCodes.Ldarg_0)
                    .Emit(OpCodes.Ret)
                    .MarkLabel(next);
                }
            }

            var staticProviderIndex   = getServiceMethod.Generator.DefineLocal(typeSystem.GetType("System.Int32"));
            var staticProviderNext    = getServiceMethod.Generator.DefineLabel();
            var staticProviderFailed  = getServiceMethod.Generator.DefineLabel();
            var staticProviderEnd     = getServiceMethod.Generator.DefineLabel();
            var staticProviderElement = getServiceMethod.Generator.DefineLocal(so);

            getServiceMethod.Generator
            //start: if(_staticProviders == null) goto: end
            .LdThisFld(staticProvidersField)
            .Brfalse(staticProviderEnd)
            // var c = 0
            .Ldc_I4(0)
            .Stloc(staticProviderIndex)
            // next:
            .MarkLabel(staticProviderNext)
            // if(c >= _staticProviders.Length) goto: end
            .Ldloc(staticProviderIndex)
            .LdThisFld(staticProvidersField)
            .Ldlen()
            .Bge(staticProviderEnd)
            // var obj = _staticProviders[c]
            .LdThisFld(staticProvidersField)
            .Ldloc(staticProviderIndex)
            .Ldelem_ref()
            // dup
            .Stloc(staticProviderElement)
            .Ldarg(1)
            .Ldloc(staticProviderElement)
            // if(obj.GetType().Equals(arg1)) return obj; else goto failed;
            .EmitCall(getTypeFromObject)
            .EmitCall(isAssignableFrom)
            .Brfalse(staticProviderFailed)
            .Ldloc(staticProviderElement)
            .Ret()
            // failed:
            .MarkLabel(staticProviderFailed)
            // c++
            .Ldloc(staticProviderIndex)
            .Ldc_I4(1)
            .Add()
            .Stloc(staticProviderIndex)
            // goto: start
            .Br(staticProviderNext)
            // end:
            .MarkLabel(staticProviderEnd);

            var noParentProvider = getServiceMethod.Generator.DefineLabel();

            getServiceMethod.Generator
            .LdThisFld(_parentServiceProviderField)
            .Brfalse(noParentProvider)
            .LdThisFld(_parentServiceProviderField)
            .Ldarg(1)
            .EmitCall(getServiceInterfaceMethod)
            .Emit(OpCodes.Ret)
            .MarkLabel(noParentProvider)
            .Ldnull()
            .Ret();

            var ctor = builder.DefineConstructor(false,
                                                 mappings.ServiceProvider,
                                                 staticProvidersField.FieldType,
                                                 systemString);

            ctor.Generator
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Call, so.Constructors.First())
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldarg_1)
            .Emit(OpCodes.Stfld, _parentServiceProviderField)
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldarg_2)
            .Emit(OpCodes.Stfld, staticProvidersField);
            if (baseUriField != null)
            {
                var noUri = ctor.Generator.DefineLabel();
                ctor.Generator
                .Emit(OpCodes.Ldarg_3)
                .Brfalse(noUri)
                .Emit(OpCodes.Ldarg_0)
                .Emit(OpCodes.Ldarg_3)
                .Newobj(systemUri.FindConstructor(new List <IXamlType>
                {
                    typeSystem.GetType("System.String")
                }))
                .Emit(OpCodes.Stfld, baseUriField)
                .MarkLabel(noUri);
            }

            foreach (var feature in ctorCallbacks)
            {
                feature(ctor.Generator);
            }

            emitMappings.ContextTypeBuilderCallback?.Invoke(builder, ctor.Generator);

            // We are calling this last to ensure that our own services are ready
            if (_innerServiceProviderField != null)
            {
                ctor.Generator
                // _innerSp = InnerServiceProviderFactory(this)
                .Ldarg_0()
                .Ldarg_0()
                .EmitCall(mappings.InnerServiceProviderFactoryMethod)
                .Stfld(_innerServiceProviderField);
            }

            ctor.Generator.Emit(OpCodes.Ret);

            Constructor = ctor;
            CreateCallbacks.Add(() => { parentBuilder.CreateType(); });

            if (ParentListField != null)
            {
                EmitPushPopParent(builder, typeSystem);
            }

            CreateAllTypes();
            ContextType = builder.CreateType();
        }
Beispiel #17
0
        public static IXamlField EmitNamespaceInfoProvider(TransformerConfiguration configuration,
                                                           IXamlTypeBuilder <IXamlILEmitter> typeBuilder, XamlDocument document)
        {
            var iface = configuration.TypeMappings.XmlNamespaceInfoProvider;

            typeBuilder.AddInterfaceImplementation(iface);
            var method         = iface.FindMethod(m => m.Name == "get_XmlNamespaces");
            var instField      = typeBuilder.DefineField(method.ReturnType, "_services", false, false);
            var singletonField = typeBuilder.DefineField(iface, "Singleton", true, true);

            var impl = typeBuilder.DefineMethod(method.ReturnType, null, method.Name, true, false, true);

            typeBuilder.DefineProperty(method.ReturnType, "XmlNamespaces", null, impl);
            impl.Generator
            .LdThisFld(instField)
            .Ret();

            var infoType = method.ReturnType.GenericArguments[1].GenericArguments[0];

            var ctor     = typeBuilder.DefineConstructor(false);
            var listType = configuration.TypeSystem.FindType("System.Collections.Generic.List`1")
                           .MakeGenericType(infoType);
            var listInterfaceType = configuration.TypeSystem.FindType("System.Collections.Generic.IReadOnlyList`1")
                                    .MakeGenericType(infoType);
            var listAdd = listType.FindMethod("Add", configuration.WellKnownTypes.Void, true, infoType);

            var dictionaryType = configuration.TypeSystem.FindType("System.Collections.Generic.Dictionary`2")
                                 .MakeGenericType(configuration.WellKnownTypes.String, listInterfaceType);
            var dictionaryAdd = dictionaryType.FindMethod("Add", configuration.WellKnownTypes.Void, true,
                                                          configuration.WellKnownTypes.String, listInterfaceType);

            var dicLocal  = ctor.Generator.DefineLocal(dictionaryType);
            var listLocal = ctor.Generator.DefineLocal(listType);

            ctor.Generator
            .Ldarg_0()
            .Emit(OpCodes.Call, configuration.WellKnownTypes.Object.FindConstructor())
            .Emit(OpCodes.Newobj, dictionaryType.FindConstructor())
            .Stloc(dicLocal)
            .Ldarg_0()
            .Ldloc(dicLocal)
            .Stfld(instField);

            foreach (var alias in document.NamespaceAliases)
            {
                ctor.Generator
                .Newobj(listType.FindConstructor(new List <IXamlType>()))
                .Stloc(listLocal);

                var resolved = Transform.NamespaceInfoHelper.TryResolve(configuration, alias.Value);
                if (resolved != null)
                {
                    foreach (var rns in resolved)
                    {
                        ctor.Generator
                        .Ldloc(listLocal)
                        .Newobj(infoType.FindConstructor());
                        if (rns.ClrNamespace != null)
                        {
                            ctor.Generator
                            .Dup()
                            .Ldstr(rns.ClrNamespace)
                            .EmitCall(infoType.FindMethod(m => m.Name == "set_ClrNamespace"));
                        }

                        var asmName = rns.AssemblyName ?? rns.Assembly?.Name;
                        if (asmName != null)
                        {
                            ctor.Generator
                            .Dup()
                            .Ldstr(asmName)
                            .EmitCall(infoType.FindMethod(m => m.Name == "set_ClrAssemblyName"));
                        }

                        ctor.Generator.EmitCall(listAdd);
                    }
                }

                ctor.Generator
                .Ldloc(dicLocal)
                .Ldstr(alias.Key)
                .Ldloc(listLocal)
                .EmitCall(dictionaryAdd, true);
            }

            ctor.Generator.Ret();

            var sctor = typeBuilder.DefineConstructor(true);

            sctor.Generator
            .Newobj(ctor)
            .Stsfld(singletonField)
            .Ret();

            return(singletonField);
            //return typeBuilder.CreateType().Fields.First(f => f.Name == "Singleton");
        }