Exemplo n.º 1
0
 private CompilerTestBase(IXamlIlTypeSystem typeSystem)
 {
     _typeSystem   = typeSystem;
     Configuration = new XamlIlTransformerConfiguration(typeSystem,
                                                        typeSystem.FindAssembly("XamlParserTests"),
                                                        new XamlIlLanguageTypeMappings(typeSystem)
     {
         XmlnsAttributes =
         {
             typeSystem.GetType("XamlParserTests.XmlnsDefinitionAttribute"),
         },
         ContentAttributes =
         {
             typeSystem.GetType("XamlParserTests.ContentAttribute")
         },
         UsableDuringInitializationAttributes =
         {
             typeSystem.GetType("XamlParserTests.UsableDuringInitializationAttribute")
         },
         DeferredContentPropertyAttributes =
         {
             typeSystem.GetType("XamlParserTests.DeferredContentAttribute")
         },
         RootObjectProvider                 = typeSystem.GetType("XamlParserTests.ITestRootObjectProvider"),
         UriContextProvider                 = typeSystem.GetType("XamlParserTests.ITestUriContext"),
         ProvideValueTarget                 = typeSystem.GetType("XamlParserTests.ITestProvideValueTarget"),
         ParentStackProvider                = typeSystem.GetType("XamlIl.Runtime.IXamlIlParentStackProviderV1"),
         XmlNamespaceInfoProvider           = typeSystem.GetType("XamlIl.Runtime.IXamlIlXmlNamespaceInfoProviderV1"),
         MarkupExtensionCustomResultHandler = typeSystem.GetType("XamlParserTests.CompilerTestBase")
                                              .Methods.First(m => m.Name == "ApplyNonMatchingMarkupExtension")
     }
                                                        );
 }
Exemplo n.º 2
0
        public XamlIlLanguageTypeMappings(IXamlIlTypeSystem typeSystem)
        {
            ServiceProvider       = typeSystem.GetType("System.IServiceProvider");
            TypeDescriptorContext = typeSystem.GetType("System.ComponentModel.ITypeDescriptorContext");
            SupportInitialize     = typeSystem.GetType("System.ComponentModel.ISupportInitialize");
            var tconv = typeSystem.GetType("System.ComponentModel.TypeConverterAttribute");

            if (tconv != null)
            {
                TypeConverterAttributes.Add(tconv);
            }
        }
Exemplo n.º 3
0
            public AttributeResolver(IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings)
            {
                _typeConverterAttribute = mappings.TypeConverterAttributes.First();

                void AddType(IXamlIlType type, IXamlIlType conv)
                => _converters.Add(new KeyValuePair <IXamlIlType, IXamlIlType>(type, conv));

                void Add(string type, string conv)
                => AddType(typeSystem.GetType(type), typeSystem.GetType(conv));

                Add("Avalonia.Media.Imaging.IBitmap", "Avalonia.Markup.Xaml.Converters.BitmapTypeConverter");
                var ilist = typeSystem.GetType("System.Collections.Generic.IList`1");

                AddType(ilist.MakeGenericType(typeSystem.GetType("Avalonia.Point")),
                        typeSystem.GetType("Avalonia.Markup.Xaml.Converters.PointsListTypeConverter"));
                Add("Avalonia.Controls.Templates.IMemberSelector",
                    "Avalonia.Markup.Xaml.Converters.MemberSelectorTypeConverter");
                Add("Avalonia.Controls.WindowIcon", "Avalonia.Markup.Xaml.Converters.IconTypeConverter");
                Add("System.Globalization.CultureInfo", "System.ComponentModel.CultureInfoConverter");
                Add("System.Uri", "Avalonia.Markup.Xaml.Converters.AvaloniaUriTypeConverter");
                Add("System.TimeSpan", "Avalonia.Markup.Xaml.Converters.TimeSpanTypeConverter");
                Add("Avalonia.Media.FontFamily", "Avalonia.Markup.Xaml.Converters.FontFamilyTypeConverter");
                _avaloniaList          = typeSystem.GetType("Avalonia.Collections.AvaloniaList`1");
                _avaloniaListConverter = typeSystem.GetType("Avalonia.Collections.AvaloniaListConverter`1");
            }
 public static XamlIlTransformerConfiguration Configure(IXamlIlTypeSystem typeSystem)
 {
     return(new XamlIlTransformerConfiguration(typeSystem,
                                               typeSystem.FindAssembly("Benchmarks"),
                                               new XamlIlLanguageTypeMappings(typeSystem)
     {
         XmlnsAttributes =
         {
             typeSystem.GetType("Portable.Xaml.Markup.XmlnsDefinitionAttribute"),
         },
         ContentAttributes =
         {
             typeSystem.GetType("Benchmarks.ContentAttribute")
         },
         RootObjectProvider = typeSystem.GetType("Portable.Xaml.IRootObjectProvider"),
         ParentStackProvider = typeSystem.GetType("XamlIl.Runtime.IXamlIlParentStackProviderV1")
     }));
 }
 public XamlIlTypeWellKnownTypes(IXamlIlTypeSystem typeSystem)
 {
     Void            = typeSystem.GetType("System.Void");
     String          = typeSystem.GetType("System.String");
     Object          = typeSystem.GetType("System.Object");
     CultureInfo     = typeSystem.GetType("System.Globalization.CultureInfo");
     IFormatProvider = typeSystem.GetType("System.IFormatProvider");
     IList           = typeSystem.GetType("System.Collections.IList");
     IListOfT        = typeSystem.GetType("System.Collections.Generic.IList`1");
     NullableT       = typeSystem.GetType("System.Nullable`1");
 }
Exemplo n.º 6
0
        private void EmitPushPopParent(IXamlIlTypeBuilder builder, IXamlIlTypeSystem 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 });

            builder.DefineMethod(@void, new[] { so }, PushParentMethodName, true, false, false)
            .Generator
            .LdThisFld(ParentListField)
            .Ldarg(1)
            .EmitCall(objectListType.FindMethod("Add", @void,
                                                false, so))
            .Ldarg_0()
            .Ldarg(1)
            .Stfld(PropertyTargetObject)
            .Ret();

            var pop = builder.DefineMethod(@void, new IXamlIlType[0], 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];
            .Ldarg_0()
            .LdThisFld(ParentListField)
            .Ldloc(idx)
            .EmitCall(objectListType.FindMethod(m => m.Name == "get_Item"))
            .Stfld(PropertyTargetObject)
            // _parents.RemoveAt(idx);
            .LdThisFld(ParentListField)
            .Ldloc(idx).EmitCall(objectListType.FindMethod(m => m.Name == "RemoveAt"))
            .Ret();
        }
Exemplo n.º 7
0
 public CompilerTestBase(IXamlIlTypeSystem typeSystem)
 {
     _typeSystem   = typeSystem;
     Configuration = new XamlIlTransformerConfiguration(typeSystem,
                                                        typeSystem.FindAssembly("XamlParserTests"),
                                                        new XamlIlLanguageTypeMappings(typeSystem)
     {
         XmlnsAttributes =
         {
             typeSystem.FindType("XamlParserTests.XmlnsDefinitionAttribute"),
         },
         ContentAttributes =
         {
             typeSystem.FindType("XamlParserTests.ContentAttribute")
         },
         RootObjectProvider = typeSystem.FindType("XamlParserTests.ITestRootObjectProvider"),
         ApplyNonMatchingMarkupExtension = typeSystem.GetType("XamlParserTests.CompilerTestBase")
                                           .Methods.First(m => m.Name == "ApplyNonMatchingMarkupExtension")
     }
                                                        );
 }
Exemplo n.º 8
0
        private XamlIlContextDefinition(IXamlIlTypeBuilder parentBuilder,
                                        IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings)
        {
            var so      = typeSystem.GetType("System.Object");
            var builder = parentBuilder.DefineSubType(so, "Context", true);

            builder.DefineGenericParameters(new[]
            {
                new KeyValuePair <string, XamlIlGenericParameterConstraint>("TTarget",
                                                                            new XamlIlGenericParameterConstraint
                {
                    IsClass = true
                })
            });
            var rootObjectField = builder.DefineField(builder.GenericParameters[0], "RootObject", 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 <IXamlIlType>();
            var ctorCallbacks = new List <Action <IXamlIlEmitter> >();

            if (mappings.RootObjectProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.RootObjectProvider);
                var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, 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();

                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, 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 <IXamlIlType>()))
                                  .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, ProvideTargetObjectName, true, false);
                PropertyTargetProperty = builder.DefineField(so, 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);
            }

            IXamlIlField baseUriField = null;

            if (mappings.UriContextProvider != null)
            {
                baseUriField = builder.DefineField(systemUri, "_baseUri", false, false);
                builder.AddInterfaceImplementation(mappings.UriContextProvider);
                var getter = builder.DefineMethod(systemUri, new IXamlIlType[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 <IXamlIlType>
                {
                    typeSystem.GetType("System.String")
                }))
                .Emit(OpCodes.Stfld, baseUriField)
                .MarkLabel(noUri);
            }

            foreach (var feature in ctorCallbacks)
            {
                feature(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(); });

            EmitPushPopParent(builder, typeSystem);

            CreateAllTypes();
            ContextType = builder.CreateType();
        }
Exemplo n.º 9
0
        public static XamlIlContext GenerateContextClass(IXamlIlTypeBuilder builder,
                                                         IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings,
                                                         IXamlIlType rootType)
        {
            var rootObjectField = builder.DefineField(rootType, "RootObject", true, false);
            var so          = typeSystem.GetType("System.Object");
            var systemType  = typeSystem.GetType("System.Type");
            var runtimeType = typeSystem.GetType("System.RuntimeTypeHandle");

            var ownServices = new List <IXamlIlType>();

            if (mappings.RootObjectProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.RootObjectProvider);
                var getRootObject = builder.DefineMethod(so, new IXamlIlType[0],
                                                         "get_RootObject", true, false, true);
                builder.DefineProperty(so, "RootObject", null, getRootObject);
                getRootObject.Generator
                .Emit(OpCodes.Ldarg_0)
                .Emit(OpCodes.Ldfld, rootObjectField)
                .Emit(OpCodes.Ret);
                ownServices.Add(mappings.RootObjectProvider);
            }

            var spField = builder.DefineField(mappings.ServiceProvider, "_sp", false, false);

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

            if (ownServices.Count != 0)
            {
                var compare = systemType.FindMethod("Equals", typeSystem.GetType("System.Boolean"),
                                                    false, systemType);
                var fromHandle = systemType.Methods.First(m => m.Name == "GetTypeFromHandle");

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

            getServiceMethod.Generator
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldfld, spField)
            .Emit(OpCodes.Ldarg_1)
            .Emit(OpCodes.Callvirt, mappings.ServiceProvider.FindMethod("GetService", so, false, systemType))
            .Emit(OpCodes.Ret);


            var ctor = builder.DefineConstructor(mappings.ServiceProvider);

            ctor.Generator
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Call, so.Constructors.First())
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldarg_1)
            .Emit(OpCodes.Stfld, spField)
            .Emit(OpCodes.Ret);


            return(new XamlIlContext
            {
                Constructor = ctor,
                RootObjectField = rootObjectField,
                ContextType = builder.CreateType()
            });
        }
Exemplo n.º 10
0
        public static XamlIlLanguageTypeMappings Configure(IXamlIlTypeSystem typeSystem)
        {
            var runtimeHelpers         = typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.XamlIlRuntimeHelpers");
            var assignBindingAttribute = typeSystem.GetType("Avalonia.Data.AssignBindingAttribute");
            var bindingType            = typeSystem.GetType("Avalonia.Data.IBinding");
            var rv = new XamlIlLanguageTypeMappings(typeSystem)
            {
                SupportInitialize = typeSystem.GetType("System.ComponentModel.ISupportInitialize"),
                XmlnsAttributes   =
                {
                    typeSystem.GetType("Avalonia.Metadata.XmlnsDefinitionAttribute"),
                },
                ContentAttributes =
                {
                    typeSystem.GetType("Avalonia.Metadata.ContentAttribute")
                },
                ProvideValueTarget = typeSystem.GetType("Avalonia.Markup.Xaml.IProvideValueTarget"),
                RootObjectProvider = typeSystem.GetType("Avalonia.Markup.Xaml.IRootObjectProvider"),
                RootObjectProviderIntermediateRootPropertyName = "IntermediateRootObject",
                UriContextProvider  = typeSystem.GetType("Avalonia.Markup.Xaml.IUriContext"),
                ParentStackProvider =
                    typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlParentStackProvider"),

                XmlNamespaceInfoProvider =
                    typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlXmlNamespaceInfoProvider"),
                DeferredContentPropertyAttributes    = { typeSystem.GetType("Avalonia.Metadata.TemplateContentAttribute") },
                DeferredContentExecutorCustomization =
                    runtimeHelpers.FindMethod(m => m.Name == "DeferredTransformationFactoryV1"),
                UsableDuringInitializationAttributes =
                {
                    typeSystem.GetType("Avalonia.Metadata.UsableDuringInitializationAttribute"),
                },
                InnerServiceProviderFactoryMethod =
                    runtimeHelpers.FindMethod(m => m.Name == "CreateInnerServiceProviderV1"),
                ProvideValueTargetPropertyEmitter = XamlIlAvaloniaPropertyHelper.Emit,
            };

            rv.CustomAttributeResolver    = new AttributeResolver(typeSystem, rv);
            rv.ContextTypeBuilderCallback = (b, c) => EmitNameScopeField(rv, typeSystem, b, c);
            return(rv);
        }
Exemplo n.º 11
0
        private XamlIlContext(IXamlIlTypeBuilder builder,
                              IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings,
                              IXamlIlType rootType, IEnumerable <IXamlIlField> staticProviders, string baseUri)
        {
            RootObjectField             = builder.DefineField(rootType, "RootObject", true, false);
            _parentServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_sp", false, false);
            if (mappings.InnerServiceProviderFactoryMethod != null)
            {
                _innerServiceProviderField = builder.DefineField(mappings.ServiceProvider, "_innerSp", false, false);
            }
            var so         = typeSystem.GetType("System.Object");
            var systemType = typeSystem.GetType("System.Type");
            var getServiceInterfaceMethod = mappings.ServiceProvider.FindMethod("GetService", so, false, systemType);

            var ownServices   = new List <IXamlIlType>();
            var ctorCallbacks = new List <Action <IXamlIlEmitter> >();

            if (mappings.RootObjectProvider != null)
            {
                builder.AddInterfaceImplementation(mappings.RootObjectProvider);
                var rootGen = ImplementInterfacePropertyGetter(builder, mappings.RootObjectProvider, "RootObject")
                              .Generator;
                var tryParent          = rootGen.DefineLabel();
                var fail               = rootGen.DefineLabel();
                var parentRootProvider = rootGen.DefineLocal(mappings.RootObjectProvider);
                rootGen
                // if(RootObject!=null) return RootObject;
                .LdThisFld(RootObjectField)
                .Brfalse(tryParent)
                .LdThisFld(RootObjectField)
                .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();

                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, "ParentsStack", true, false);

                var enumerator = EmitParentEnumerable(typeSystem, builder, mappings);
                CreateCallbacks.Add(enumerator.createCallback);
                _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 <IXamlIlType>()))
                                  .Emit(OpCodes.Stfld, ParentListField)
                                  .Emit(OpCodes.Ldarg_0)
                                  .Emit(OpCodes.Ldarg_0)
                                  .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, "ProvideTargetObject", true, false);
                PropertyTargetProperty = builder.DefineField(so, "ProvideTargetProperty", true, false);
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetObject")
                .Generator.LdThisFld(PropertyTargetObject).Ret();
                ImplementInterfacePropertyGetter(builder, mappings.ProvideValueTarget, "TargetProperty")
                .Generator.LdThisFld(PropertyTargetProperty).Ret();
                ownServices.Add(mappings.ProvideValueTarget);
            }

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


                var noCache = getter.Generator.DefineLabel();
                getter.Generator
                .LdThisFld(cached)
                .Brfalse(noCache)
                .LdThisFld(cached)
                .Ret()
                .MarkLabel(noCache)
                .Ldarg_0()
                .Ldstr(baseUri)
                .Newobj(systemUri.FindConstructor(new List <IXamlIlType>
                {
                    typeSystem.GetType("System.String")
                }))
                .Stfld(cached)
                .LdThisFld(cached)
                .Ret();

                setter.Generator
                .Ldarg_0()
                .Ldarg(1)
                .Stfld(cached)
                .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 fromHandle = systemType.Methods.First(m => m.Name == "GetTypeFromHandle");

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

            if (staticProviders != null)
            {
                foreach (var sprov in staticProviders)
                {
                    var next = getServiceMethod.Generator.DefineLabel();
                    getServiceMethod.Generator
                    .Ldtoken(sprov.FieldType)
                    .EmitCall(fromHandle)
                    .Ldarg(1)
                    .EmitCall(compare)
                    .Brfalse(next)
                    .Ldsfld(sprov)
                    .Ret()
                    .MarkLabel(next);
                }
            }

            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);

            ctor.Generator
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Call, so.Constructors.First())
            .Emit(OpCodes.Ldarg_0)
            .Emit(OpCodes.Ldarg_1)
            .Emit(OpCodes.Stfld, _parentServiceProviderField);
            foreach (var feature in ctorCallbacks)
            {
                feature(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(() => { ContextType = builder.CreateType(); });
            ContextType = builder;
        }