public AvaloniaXamlIlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings, IXamlTypeBuilder <IXamlILEmitter> contextTypeBuilder) : this(configuration, emitMappings) { _contextType = CreateContextType(contextTypeBuilder); }
public XamlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <TBackendEmitter, TEmitResult> emitMappings, bool fillWithDefaults) { _configuration = configuration; _emitMappings = emitMappings; if (fillWithDefaults) { Transformers = new List <IXamlAstTransformer> { new KnownDirectivesTransformer(), new XamlIntrinsicsTransformer(), new XArgumentsTransformer(), new TypeReferenceResolver(), new MarkupExtensionTransformer(), new PropertyReferenceResolver(), new ContentConvertTransformer(), new ResolveContentPropertyTransformer(), new ResolvePropertyValueAddersTransformer(), new ConvertPropertyValuesToAssignmentsTransformer(), new ConstructableObjectTransformer() }; SimplificationTransformers = new List <IXamlAstTransformer> { new FlattenAstTransformer() }; } }
public RuntimeContext(IXamlType definition, IXamlType constructedType, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> mappings, string baseUri, List <IXamlField> staticProviders) : base(definition, constructedType, mappings, (context, codegen) => { if (staticProviders?.Count > 0) { var so = codegen.TypeSystem.GetType("System.Object"); codegen.Ldc_I4(staticProviders.Count) .Newarr(so); for (var c = 0; c < staticProviders.Count; c++) { codegen .Dup() .Ldc_I4(c) .Ldsfld(staticProviders[c]) .Castclass(so) .Stelem_ref(); } } else { codegen.Ldnull(); } codegen.Ldstr(baseUri) .Newobj(context.Constructor); }) { }
public XamlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <TBackendEmitter, TEmitResult> emitMappings, bool fillWithDefaults) { _configuration = configuration; _emitMappings = emitMappings; if (fillWithDefaults) { Transformers = new List <IXamlAstTransformer> { new KnownDirectivesTransformer(), new XamlIntrinsicsTransformer(), new XArgumentsTransformer(), new TypeReferenceResolver(), new MarkupExtensionTransformer(), new TextNodeMerger(), new PropertyReferenceResolver(), new ContentConvertTransformer(), // This should come before actual content property processing new RemoveWhitespaceBetweenPropertyValuesTransformer(), new ResolveContentPropertyTransformer(), new ResolvePropertyValueAddersTransformer(), new ApplyWhitespaceNormalization(), new ConvertPropertyValuesToAssignmentsTransformer(), new ConstructableObjectTransformer() }; SimplificationTransformers = new List <IXamlAstTransformer> { new FlattenAstTransformer() }; } }
public static (XamlLanguageTypeMappings language, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emit) Configure(IXamlTypeSystem 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 XamlLanguageTypeMappings(typeSystem) { SupportInitialize = typeSystem.GetType("System.ComponentModel.ISupportInitialize"), XmlnsAttributes = { typeSystem.GetType("Avalonia.Metadata.XmlnsDefinitionAttribute"), }, ContentAttributes = { typeSystem.GetType("Avalonia.Metadata.ContentAttribute") }, WhitespaceSignificantCollectionAttributes = { typeSystem.GetType("Avalonia.Metadata.WhitespaceSignificantCollectionAttribute") }, TrimSurroundingWhitespaceAttributes = { typeSystem.GetType("Avalonia.Metadata.TrimSurroundingWhitespaceAttribute") }, 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") }, DeferredContentExecutorCustomizationDefaultTypeParameter = typeSystem.GetType("Avalonia.Controls.IControl"), DeferredContentExecutorCustomizationTypeParameterDeferredContentAttributePropertyNames = new List <string> { "TemplateResultType" }, DeferredContentExecutorCustomization = runtimeHelpers.FindMethod(m => m.Name == "DeferredTransformationFactoryV2"), UsableDuringInitializationAttributes = { typeSystem.GetType("Avalonia.Metadata.UsableDuringInitializationAttribute"), }, InnerServiceProviderFactoryMethod = runtimeHelpers.FindMethod(m => m.Name == "CreateInnerServiceProviderV1"), }; rv.CustomAttributeResolver = new AttributeResolver(typeSystem, rv); var emit = new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> { ProvideValueTargetPropertyEmitter = XamlIlAvaloniaPropertyHelper.EmitProvideValueTarget, ContextTypeBuilderCallback = (b, c) => EmitNameScopeField(rv, typeSystem, b, c) }; return(rv, emit); }
public RobustXamlILCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings, bool fillWithDefaults) : base(configuration, emitMappings, fillWithDefaults) { Transformers.Add(new AddNameScopeRegistration()); Transformers.Add(new RobustMarkRootObjectScopeNode()); Emitters.Add(new AddNameScopeRegistration.Emitter()); Emitters.Add(new RobustMarkRootObjectScopeNode.Emitter()); }
public WinUIXamlILCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings) : base(configuration, emitMappings, true) { this.AddWinUIPhases(); Emitters.Add(new XamlDirectConversionEmitter()); Emitters.Add(new XamlDirectNewObjectEmitter()); Emitters.Add(new XamlDirectSetterEmitter()); Emitters.Add(new XamlDirectAdderSetterEmitter()); Emitters.Add(new XamlDirectEventSetterEmitter()); }
public ILEmitContext(IXamlILEmitter emitter, TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings, XamlRuntimeContext <IXamlILEmitter, XamlILNodeEmitResult> runtimeContext, IXamlLocal contextLocal, Func <string, IXamlType, IXamlTypeBuilder <IXamlILEmitter> > createSubType, IFileSource file, IEnumerable <object> emitters) : base(emitter, configuration, emitMappings, runtimeContext, contextLocal, createSubType, file, emitters) { EnableIlVerification = configuration.GetOrCreateExtra <ILEmitContextSettings>().EnableILVerification; }
private AvaloniaXamlIlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings) : base(configuration, emitMappings, true) { _configuration = configuration; void InsertAfter <T>(params IXamlAstTransformer[] t) => Transformers.InsertRange(Transformers.FindIndex(x => x is T) + 1, t); void InsertBefore <T>(params IXamlAstTransformer[] t) => Transformers.InsertRange(Transformers.FindIndex(x => x is T), t); // Before everything else Transformers.Insert(0, new XNameTransformer()); Transformers.Insert(1, new IgnoredDirectivesTransformer()); Transformers.Insert(2, _designTransformer = new AvaloniaXamlIlDesignPropertiesTransformer()); Transformers.Insert(3, _bindingTransformer = new AvaloniaBindingExtensionTransformer()); // Targeted InsertBefore <PropertyReferenceResolver>( new AvaloniaXamlIlResolveClassesPropertiesTransformer(), new AvaloniaXamlIlTransformInstanceAttachedProperties(), new AvaloniaXamlIlTransformSyntheticCompiledBindingMembers()); InsertAfter <PropertyReferenceResolver>( new AvaloniaXamlIlAvaloniaPropertyResolver(), new AvaloniaXamlIlReorderClassesPropertiesTransformer() ); InsertBefore <ContentConvertTransformer>( new AvaloniaXamlIlBindingPathParser(), new AvaloniaXamlIlSelectorTransformer(), new AvaloniaXamlIlControlTemplateTargetTypeMetadataTransformer(), new AvaloniaXamlIlPropertyPathTransformer(), new AvaloniaXamlIlSetterTransformer(), new AvaloniaXamlIlConstructorServiceProviderTransformer(), new AvaloniaXamlIlTransitionsTypeMetadataTransformer(), new AvaloniaXamlIlResolveByNameMarkupExtensionReplacer() ); // After everything else InsertBefore <NewObjectTransformer>( new AddNameScopeRegistration(), new AvaloniaXamlIlDataContextTypeTransformer(), new AvaloniaXamlIlBindingPathTransformer(), new AvaloniaXamlIlCompiledBindingsMetadataRemover() ); Transformers.Add(new AvaloniaXamlIlMetadataRemover()); Transformers.Add(new AvaloniaXamlIlRootObjectScope()); Emitters.Add(new AvaloniaNameScopeRegistrationXamlIlNodeEmitter()); Emitters.Add(new AvaloniaXamlIlRootObjectScope.Emitter()); }
public XamlImperativeCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <TBackendEmitter, TEmitResult> emitMappings, bool fillWithDefaults) : base(configuration, emitMappings, fillWithDefaults) { if (fillWithDefaults) { Transformers.AddRange(new IXamlAstTransformer[] { new NewObjectTransformer(), new DeferredContentTransformer(), new TopDownInitializationTransformer(), }); } }
internal static (XamlLanguageTypeMappings, XamlLanguageEmitMappings <TBackendEmitter, TEmitResult>) Configure <TBackendEmitter, TEmitResult>(CecilTypeSystem typeSystem) where TEmitResult : IXamlEmitResult { var langaugeMappings = new XamlLanguageTypeMappings(typeSystem, useDefault: false) { ServiceProvider = typeSystem.GetType("Microsoft.UI.Xaml.IXamlServiceProvider"), ContentAttributes = { typeSystem.GetType("Microsoft.UI.Xaml.Markup.ContentPropertyAttribute"), typeSystem.GetType("Windows.UI.Xaml.Markup.ContentPropertyAttribute"), } }; var emitMappings = new XamlLanguageEmitMappings <TBackendEmitter, TEmitResult>(); return(langaugeMappings, emitMappings); }
public AvaloniaXamlIlCompiler(TransformerConfiguration configuration, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings, IXamlType contextType) : this(configuration, emitMappings) { _contextType = contextType; }
static bool?CompileCore(IBuildEngine engine, CecilTypeSystem typeSystem) { var asm = typeSystem.TargetAssemblyDefinition; var embrsc = new EmbeddedResources(asm); if (embrsc.Resources.Count(CheckXamlName) == 0) { // Nothing to do return(null); } var xamlLanguage = new XamlLanguageTypeMappings(typeSystem) { XmlnsAttributes = { typeSystem.GetType("Avalonia.Metadata.XmlnsDefinitionAttribute"), }, ContentAttributes = { typeSystem.GetType("Robust.Client.UserInterface.XAML.ContentAttribute") }, UsableDuringInitializationAttributes = { typeSystem.GetType("Robust.Client.UserInterface.XAML.UsableDuringInitializationAttribute") }, DeferredContentPropertyAttributes = { typeSystem.GetType("Robust.Client.UserInterface.XAML.DeferredContentAttribute") }, RootObjectProvider = typeSystem.GetType("Robust.Client.UserInterface.XAML.ITestRootObjectProvider"), UriContextProvider = typeSystem.GetType("Robust.Client.UserInterface.XAML.ITestUriContext"), ProvideValueTarget = typeSystem.GetType("Robust.Client.UserInterface.XAML.ITestProvideValueTarget"), }; var emitConfig = new XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> { ContextTypeBuilderCallback = (b, c) => EmitNameScopeField(xamlLanguage, typeSystem, b, c) }; var transformerconfig = new TransformerConfiguration( typeSystem, typeSystem.TargetAssembly, xamlLanguage, XamlXmlnsMappings.Resolve(typeSystem, xamlLanguage), CustomValueConverter); var contextDef = new TypeDefinition("CompiledRobustXaml", "XamlIlContext", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); asm.MainModule.Types.Add(contextDef); var contextClass = XamlILContextDefinition.GenerateContextClass(typeSystem.CreateTypeBuilder(contextDef), typeSystem, xamlLanguage, emitConfig); var compiler = new RobustXamlILCompiler(transformerconfig, emitConfig, true); var loaderDispatcherDef = new TypeDefinition("CompiledRobustXaml", "!XamlLoader", TypeAttributes.Class, asm.MainModule.TypeSystem.Object); var loaderDispatcherMethod = new MethodDefinition("TryLoad", MethodAttributes.Static | MethodAttributes.Public, asm.MainModule.TypeSystem.Object) { Parameters = { new ParameterDefinition(asm.MainModule.TypeSystem.String) } }; loaderDispatcherDef.Methods.Add(loaderDispatcherMethod); asm.MainModule.Types.Add(loaderDispatcherDef); var stringEquals = asm.MainModule.ImportReference(asm.MainModule.TypeSystem.String.Resolve().Methods.First( m => m.IsStatic && m.Name == "Equals" && m.Parameters.Count == 2 && m.ReturnType.FullName == "System.Boolean" && m.Parameters[0].ParameterType.FullName == "System.String" && m.Parameters[1].ParameterType.FullName == "System.String")); bool CompileGroup(IResourceGroup group) { var typeDef = new TypeDefinition("CompiledRobustXaml", "!" + group.Name, TypeAttributes.Class, asm.MainModule.TypeSystem.Object); //typeDef.CustomAttributes.Add(new CustomAttribute(ed)); asm.MainModule.Types.Add(typeDef); var builder = typeSystem.CreateTypeBuilder(typeDef); foreach (var res in group.Resources.Where(CheckXamlName)) { try { engine.LogMessage($"XAMLIL: {res.Name} -> {res.Uri}", MessageImportance.Low); var xaml = new StreamReader(new MemoryStream(res.FileContents)).ReadToEnd(); var parsed = XDocumentXamlParser.Parse(xaml); var initialRoot = (XamlAstObjectNode)parsed.Root; var classDirective = initialRoot.Children.OfType <XamlAstXmlDirective>() .FirstOrDefault(d => d.Namespace == XamlNamespaces.Xaml2006 && d.Name == "Class"); string classname; if (classDirective != null && classDirective.Values[0] is XamlAstTextNode tn) { classname = tn.Text; } else { classname = res.Name.Replace(".xaml", ""); } var classType = typeSystem.TargetAssembly.FindType(classname); if (classType == null) { throw new Exception($"Unable to find type '{classname}'"); } compiler.Transform(parsed); var populateName = $"Populate:{res.Name}"; var buildName = $"Build:{res.Name}"; var classTypeDefinition = typeSystem.GetTypeReference(classType).Resolve(); var populateBuilder = typeSystem.CreateTypeBuilder(classTypeDefinition); compiler.Compile(parsed, contextClass, compiler.DefinePopulateMethod(populateBuilder, parsed, populateName, classTypeDefinition == null), compiler.DefineBuildMethod(builder, parsed, buildName, true), null, (closureName, closureBaseType) => populateBuilder.DefineSubType(closureBaseType, closureName, false), res.Uri, res ); //add compiled populate method var compiledPopulateMethod = typeSystem.GetTypeReference(populateBuilder).Resolve().Methods .First(m => m.Name == populateName); const string TrampolineName = "!XamlIlPopulateTrampoline"; var trampoline = new MethodDefinition(TrampolineName, MethodAttributes.Static | MethodAttributes.Private, asm.MainModule.TypeSystem.Void); trampoline.Parameters.Add(new ParameterDefinition(classTypeDefinition)); classTypeDefinition.Methods.Add(trampoline); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Call, compiledPopulateMethod)); trampoline.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); var foundXamlLoader = false; // Find RobustXamlLoader.Load(this) and replace it with !XamlIlPopulateTrampoline(this) foreach (var method in classTypeDefinition.Methods .Where(m => !m.Attributes.HasFlag(MethodAttributes.Static))) { var i = method.Body.Instructions; for (var c = 1; c < i.Count; c++) { if (i[c].OpCode == OpCodes.Call) { var op = i[c].Operand as MethodReference; if (op != null && op.Name == TrampolineName) { foundXamlLoader = true; break; } if (op != null && op.Name == "Load" && op.Parameters.Count == 1 && op.Parameters[0].ParameterType.FullName == "System.Object" && op.DeclaringType.FullName == "Robust.Client.UserInterface.XAML.RobustXamlLoader") { if (MatchThisCall(i, c - 1)) { i[c].Operand = trampoline; foundXamlLoader = true; } } } } } if (!foundXamlLoader) { var ctors = classTypeDefinition.GetConstructors() .Where(c => !c.IsStatic).ToList(); // We can inject xaml loader into default constructor if (ctors.Count == 1 && ctors[0].Body.Instructions.Count(o => o.OpCode != OpCodes.Nop) == 3) { var i = ctors[0].Body.Instructions; var retIdx = i.IndexOf(i.Last(x => x.OpCode == OpCodes.Ret)); i.Insert(retIdx, Instruction.Create(OpCodes.Call, trampoline)); i.Insert(retIdx, Instruction.Create(OpCodes.Ldarg_0)); } else { throw new InvalidProgramException( $"No call to RobustXamlLoader.Load(this) call found anywhere in the type {classType.FullName} and type seems to have custom constructors."); } } //add compiled build method var compiledBuildMethod = typeSystem.GetTypeReference(builder).Resolve().Methods .First(m => m.Name == buildName); var parameterlessCtor = classTypeDefinition.GetConstructors() .FirstOrDefault(c => c.IsPublic && !c.IsStatic && !c.HasParameters); if (compiledBuildMethod != null && parameterlessCtor != null) { var i = loaderDispatcherMethod.Body.Instructions; var nop = Instruction.Create(OpCodes.Nop); i.Add(Instruction.Create(OpCodes.Ldarg_0)); i.Add(Instruction.Create(OpCodes.Ldstr, res.Uri)); i.Add(Instruction.Create(OpCodes.Call, stringEquals)); i.Add(Instruction.Create(OpCodes.Brfalse, nop)); if (parameterlessCtor != null) { i.Add(Instruction.Create(OpCodes.Newobj, parameterlessCtor)); } else { i.Add(Instruction.Create(OpCodes.Call, compiledBuildMethod)); } i.Add(Instruction.Create(OpCodes.Ret)); i.Add(nop); } } catch (Exception e) { engine.LogErrorEvent(new BuildErrorEventArgs("XAMLIL", "", res.FilePath, 0, 0, 0, 0, $"{res.FilePath}: {e.Message}", "", "CompileRobustXaml")); } } return(true); } if (embrsc.Resources.Count(CheckXamlName) != 0) { if (!CompileGroup(embrsc)) { return(false); } } loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ldnull)); loaderDispatcherMethod.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); return(true); }
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(); }
public static IXamlType GenerateContextClass(IXamlTypeBuilder <IXamlILEmitter> builder, IXamlTypeSystem typeSystem, XamlLanguageTypeMappings mappings, XamlLanguageEmitMappings <IXamlILEmitter, XamlILNodeEmitResult> emitMappings) { return(new XamlILContextDefinition(builder, typeSystem, mappings, emitMappings).ContextType); }