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(); }
IXamlIlType EmitTypeDescriptorContextStub(IXamlIlTypeSystem typeSystem, IXamlIlTypeBuilder builder, XamlIlLanguageTypeMappings 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 <IXamlIlType>())) .Emit(OpCodes.Throw); } MethodStub("OnComponentChanging"); MethodStub("OnComponentChanged"); return(mappings.TypeDescriptorContext); }
public IXamlIlMethodBuilder DefineBuildMethod(IXamlIlTypeBuilder typeBuilder, XamlIlDocument doc, string name, bool isPublic) { var rootGrp = (XamlIlValueWithManipulationNode)doc.Root; return(typeBuilder.DefineMethod(rootGrp.Type.GetClrType(), new[] { _configuration.TypeMappings.ServiceProvider }, name, isPublic, true, false)); }
XamlIlDocument Compile(IXamlIlTypeBuilder builder, IXamlIlType context, string xaml) { var parsed = XDocumentXamlIlParser.Parse(xaml); var compiler = new XamlIlCompiler(Configuration, true); compiler.Transform(parsed); compiler.Compile(parsed, builder, context, "Populate", "Build", "XamlIlNamespaceInfo", "http://example.com/", null); return(parsed); }
private IXamlIlMethodBuilder ImplementInterfacePropertyGetter(IXamlIlTypeBuilder builder, IXamlIlType 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 IXamlIlType[0], prefix + "get_" + name, false, false, true, originalGetter); builder.DefineProperty(originalGetter.ReturnType, prefix + name, null, gen); return(gen); }
private static void EmitNameScopeField(XamlIlLanguageTypeMappings mappings, IXamlIlTypeSystem typeSystem, IXamlIlTypeBuilder 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); }
public void Compile(XamlIlDocument doc, IXamlIlTypeBuilder typeBuilder, IXamlIlType contextType, string populateMethodName, string createMethodName, string namespaceInfoClassName, string baseUri, IFileSource fileSource) { var rootGrp = (XamlIlValueWithManipulationNode)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); }
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(); }
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(); }
public AvaloniaXamlIlCompiler(XamlIlTransformerConfiguration configuration, IXamlIlTypeBuilder contextTypeBuilder) : this(configuration) { _contextType = CreateContextType(contextTypeBuilder); }
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(); }
public static IXamlIlType GenerateContextClass(IXamlIlTypeBuilder builder, IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings) { return(new XamlIlContextDefinition(builder, typeSystem, mappings).ContextType); }
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() }); }
public IXamlIlType CreateContextType(IXamlIlTypeBuilder builder) { return(XamlIlContextDefinition.GenerateContextClass(builder, _configuration.TypeSystem, _configuration.TypeMappings)); }
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; }
public static XamlIlContext GenerateContextClass(IXamlIlTypeBuilder builder, IXamlIlTypeSystem typeSystem, XamlIlLanguageTypeMappings mappings, IXamlIlType rootType, IEnumerable <IXamlIlField> staticProviders, string baseUri) => new XamlIlContext(builder, typeSystem, mappings, rootType, staticProviders, baseUri);
public static IXamlIlField EmitNamespaceInfoProvider(XamlIlTransformerConfiguration configuration, IXamlIlTypeBuilder typeBuilder, XamlIlDocument 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 <IXamlIlType>())) .Stloc(listLocal); var resolved = 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"); }