Exemplo n.º 1
0
        public void Compile(XamlIlDocument doc, IXamlIlType contextType,
                            IXamlIlMethodBuilder populateMethod, IXamlIlMethodBuilder buildMethod,
                            IXamlIlTypeBuilder namespaceInfoBuilder,
                            Func <string, IXamlIlType, IXamlIlTypeBuilder> createClosure,
                            string baseUri, IFileSource fileSource)
        {
            var rootGrp         = (XamlIlValueWithManipulationNode)doc.Root;
            var staticProviders = new List <IXamlIlField>();

            if (namespaceInfoBuilder != null)
            {
                staticProviders.Add(
                    XamlIlNamespaceInfoHelper.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc));
            }

            var context = new XamlIlContext(contextType, rootGrp.Type.GetClrType(),
                                            _configuration.TypeMappings, baseUri, staticProviders);

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

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

            namespaceInfoBuilder?.CreateType();
        }
Exemplo n.º 2
0
        public static XamlIlDocument Parse(TextReader reader, Dictionary <string, string> compatibilityMappings = null)
        {
            var xr = XmlReader.Create(reader, new XmlReaderSettings
            {
                IgnoreWhitespace = true,
                DtdProcessing    = DtdProcessing.Ignore
            });

            xr = new CompatibleXmlReader(xr, compatibilityMappings ?? new Dictionary <string, string>());

            var root = XDocument.Load(xr, LoadOptions.SetLineInfo).Root;

            var doc = new XamlIlDocument
            {
                Root = new ParserContext(root).Parse()
            };

            foreach (var attr in root.Attributes())
            {
                if (attr.Name.NamespaceName == "http://www.w3.org/2000/xmlns/" ||
                    (attr.Name.NamespaceName == "" && attr.Name.LocalName == "xmlns"))
                {
                    var name = attr.Name.NamespaceName == "" ? "" : attr.Name.LocalName;
                    doc.NamespaceAliases[name] = attr.Value;
                }
            }

            return(doc);
        }
Exemplo n.º 3
0
        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));
        }
        public void Transform(XamlIlDocument doc,
                              Dictionary <string, string> namespaceAliases, bool strict = true)
        {
            var ctx = new XamlIlAstTransformationContext(_configuration, namespaceAliases, strict);

            var root = doc.Root;

            foreach (var transformer in Transformers)
            {
                root = root.Visit(n => transformer.Transform(ctx, n));
            }

            doc.Root = root;
        }
Exemplo n.º 5
0
        public void Transform(XamlIlDocument doc, bool strict = true)
        {
            var ctx = CreateTransformationContext(doc, strict);

            var root = doc.Root;

            ctx.RootObject = new XamlIlRootObjectNode((XamlIlAstObjectNode)root);
            foreach (var transformer in Transformers)
            {
                root = ctx.Visit(root, transformer);
            }
            foreach (var simplifier in SimplificationTransformers)
            {
                root = ctx.Visit(root, simplifier);
            }

            doc.Root = root;
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        public void Compile(XamlIlDocument doc, IXamlIlTypeBuilder typeBuilder,
                            string populateMethodName, string createMethodName, string contextClassName, string namespaceInfoClassName,
                            string baseUri)
        {
            var rootGrp         = (XamlIlValueWithManipulationNode)doc.Root;
            var staticProviders = new List <IXamlIlField>();

            IXamlIlTypeBuilder namespaceInfoBuilder = null;

            if (_configuration.TypeMappings.XmlNamespaceInfoProvider != null)
            {
                namespaceInfoBuilder = typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object,
                                                                 namespaceInfoClassName, false);
                staticProviders.Add(
                    XamlIlNamespaceInfoHelper.EmitNamespaceInfoProvider(_configuration, namespaceInfoBuilder, doc));
            }

            var contextBuilder = typeBuilder.DefineSubType(_configuration.WellKnownTypes.Object,
                                                           contextClassName, false);

            var contextType = XamlIlContext.GenerateContextClass(contextBuilder, _configuration.TypeSystem,
                                                                 _configuration.TypeMappings, rootGrp.Type.GetClrType(), staticProviders, baseUri);

            var populateMethod = typeBuilder.DefineMethod(_configuration.WellKnownTypes.Void,
                                                          new[] { _configuration.TypeMappings.ServiceProvider, rootGrp.Type.GetClrType() },
                                                          populateMethodName, true, true, false);

            IXamlIlTypeBuilder CreateSubType(string name, IXamlIlType baseType)
            => typeBuilder.DefineSubType(baseType, name, false);

            CompilePopulate(rootGrp.Manipulation, CreateSubType, populateMethod.Generator, contextType);

            var createMethod = typeBuilder.DefineMethod(rootGrp.Type.GetClrType(),
                                                        new[] { _configuration.TypeMappings.ServiceProvider }, createMethodName, true, true, false);

            CompileBuild(rootGrp.Value, CreateSubType, createMethod.Generator, contextType, populateMethod);
            namespaceInfoBuilder?.CreateType();
            contextType.CreateAllTypes();
        }
Exemplo n.º 8
0
        public void Parser_Should_Be_Able_To_Parse_A_Simple_Tree()
        {
            var root = XDocumentXamlIlParser.Parse(
                @"
<Root xmlns='rootns' xmlns:t='testns' xmlns:d='directive' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
    <Child Ext='{Extension 123, 321, Prop=test, Prop2=test2, Prop3={Extension}, Prop4=test3}'
        Other.Prop='{}Not extension'
        Prop1='123' 
        Root.AttachedProp='AttachedValue'
        t:Namespaced.AttachedProp='AttachedValue'
        d:Directive='DirectiveValue'
        d:DirectiveExt='{Extension 123}'>
        <t:SubChild Prop='321' Root.AttachedProp='AttachedValue'/>
        <Child.DottedProp>DottedValue</Child.DottedProp>
        <Root.AttachedDottedProp>AttachedValue</Root.AttachedDottedProp>
        <Child.NodeListProp>
            <SubChild/>
            <SubChild/>
        </Child.NodeListProp>
    </Child>
    <GenericType x:TypeArguments='Child,t:NamespacedGeneric(Child,GenericType ( Child, t:Namespaced) )'/>

</Root>");
            var ni             = new NullLineInfo();
            var rootType       = new XamlIlAstXmlTypeReference(ni, "rootns", "Root");
            var childType      = new XamlIlAstXmlTypeReference(ni, "rootns", "Child");
            var subChildType   = new XamlIlAstXmlTypeReference(ni, "rootns", "SubChild");
            var nsSubChildType = new XamlIlAstXmlTypeReference(ni, "testns", "SubChild");
            var namespacedType = new XamlIlAstXmlTypeReference(ni, "testns", "Namespaced");
            var extensionType  = new XamlIlAstXmlTypeReference(ni, "rootns", "Extension")
            {
                IsMarkupExtension = true
            };

            var other = new XamlIlDocument
            {
                NamespaceAliases = new Dictionary <string, string>
                {
                    [""]  = "rootns",
                    ["t"] = "testns",
                    ["d"] = "directive",
                    ["x"] = "http://schemas.microsoft.com/winfx/2006/xaml"
                },
                Root = new XamlIlAstObjectNode(ni, rootType)
                {
                    Children =
                    {
                        // <Child
                        new XamlIlAstObjectNode(ni,                                                                                                                                 childType)
                        {
                            Children =
                            {
                                // Ext='{Extension 123, 321, Prop=test, Prop2=test2}'
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       childType,                                                                                                                                                "Ext",                                                                                                                                             childType),
                                                                   new XamlIlAstObjectNode(ni,                                                                                                                                                                      extensionType)
                                {
                                    Arguments =
                                    {
                                        new XamlIlAstTextNode(ni, "123"),
                                        new XamlIlAstTextNode(ni, "321"),
                                    },
                                    Children =
                                    {
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                         new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          extensionType,                                                                                                                                                                                                                                                                                                       "Prop",                                                                                                                                            extensionType),
                                                                           new XamlIlAstTextNode(ni,                                                                                                                                                                                                                                                                                                                                   "test")),
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                         new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          extensionType,                                                                                                                                                                                                                                                                                                       "Prop2",                                                                                                                                           extensionType),
                                                                           new XamlIlAstTextNode(ni,                                                                                                                                                                                                                                                                                                                                   "test2")),
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                         new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          extensionType,                                                                                                                                                                                                                                                                                                       "Prop3",                                                                                                                                           extensionType),
                                                                           new XamlIlAstObjectNode(ni,                                                                                                                                                                                                                                                                                                                                 extensionType)),
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                         new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                          extensionType,                                                                                                                                                                                                                                                                                                       "Prop4",                                                                                                                                           extensionType),
                                                                           new XamlIlAstTextNode(ni,                                                                                                                                                                                                                                                                                                                                   "test3")),
                                    }
                                }),
                                //Other.Prop='{}Not extension'
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       new XamlIlAstXmlTypeReference(ni,                                                                                                                         "rootns",                                                                                                                                          "Other"),                                 "Prop", childType),
                                                                   new XamlIlAstTextNode(ni,                                                                                                                                                                        "Not extension")),
                                //  Prop1='123'
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       childType,                                                                                                                                                "Prop1",                                                                                                                                           childType),
                                                                   new XamlIlAstTextNode(ni,                                                                                                                                                                        "123")),
                                // Root.AttachedProp='AttachedValue'
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       rootType,                                                                                                                                                 "AttachedProp",                                                                                                                                    childType),
                                                                   new XamlIlAstTextNode(ni,                                                                                                                                                                        "AttachedValue")),
                                //t:Namespaced.AttachedProp='AttachedValue'
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       namespacedType,                                                                                                                                           "AttachedProp",                                                                                                                                    childType),
                                                                   new XamlIlAstTextNode(ni,                                                                                                                                                                        "AttachedValue")),
                                //d:Directive='DirectiveValue'>
                                new XamlIlAstXmlDirective(ni,                                                                                                                                                                                                       "directive",                                                                                                                                       "Directive",                              new[]
                                {
                                    new XamlIlAstTextNode(ni,                                                                                                                                                                                                       "DirectiveValue")
                                }),
                                //d:DirectiveExt='{Extension 123}'>
                                new XamlIlAstXmlDirective(ni,                                                                                                                                                                                                       "directive",                                                                                                                                       "DirectiveExt",                           new[]
                                {
                                    new XamlIlAstObjectNode(ni,                                                                                                                                                                                                     extensionType)
                                    {
                                        Arguments =
                                        {
                                            new XamlIlAstTextNode(ni, "123"),
                                        }
                                    }
                                }),
                                // <t:SubChild Prop='321' Root.AttachedProp='AttachedValue'/>
                                new XamlIlAstObjectNode(ni,                                                                                                                                                                                                         nsSubChildType)
                                {
                                    Children =
                                    {
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                          new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                           nsSubChildType,                                                                                                                                                                                                                                                                                                       "Prop",                                                                                                                                            nsSubChildType),
                                                                           new XamlIlAstTextNode(ni,                                                                                                                                                                                                                                                                                                                                    "321")),
                                        // Root.AttachedProp='AttachedValue'
                                        new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                                                                                                                                                                                          new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                                                                                                                                                                                           rootType,                                                                                                                                                                                                                                                                                                             "AttachedProp",                                                                                                                                    nsSubChildType),
                                                                           new XamlIlAstTextNode(ni,                                                                                                                                                                                                                                                                                                                                    "AttachedValue")),
                                    }
                                },
                                //<Child.DottedProp>DottedValue</Child.DottedProp>
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       childType,                                                                                                                                                "DottedProp",                                                                                                                                      childType),
                                                                   new[]
                                {
                                    new XamlIlAstTextNode(ni,                                                                                                                                                                                                       "DottedValue")
                                }),
                                // <Root.AttachedDottedProp>AttachedValue</Root.AttachedDottedProp>
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       rootType,                                                                                                                                                 "AttachedDottedProp",                                                                                                                              childType),
                                                                   new[]
                                {
                                    new XamlIlAstTextNode(ni,                                                                                                                                                                                                       "AttachedValue")
                                }),
                                //<Child.NodeListProp>
                                new XamlIlAstXamlPropertyValueNode(ni,                                                                                                                                                                                              new XamlIlAstNamePropertyReference(ni,
                                                                                                                                                                                                                                                                                                       childType,                                                                                                                                                "NodeListProp",                                                                                                                                    childType),
                                                                   new[]
                                {
                                    // <SubChild/>
                                    new XamlIlAstObjectNode(ni,                                                                                                                                                                                                     subChildType),
                                    // <SubChild/>
                                    new XamlIlAstObjectNode(ni,                                                                                                                                                                                                     subChildType),
                                })
                            }
                        },
                        //<GenericType x:TypeArguments='Child,t:NamespacedGeneric(Child,GenericType(Child, t:Namespaced))'/>
                        new XamlIlAstObjectNode(ni,                                                                                                                                 new XamlIlAstXmlTypeReference(ni,     "rootns",             "GenericType",
                                                                                                                                                                                                                  new[]
                        {
                            childType,
                            new XamlIlAstXmlTypeReference(ni,                                                                                                                       "testns",                             "NamespacedGeneric",  new[]
                            {
                                childType,
                                new XamlIlAstXmlTypeReference(ni,                                                                                                                   "rootns",                             "GenericType",        new[]
                                {
                                    childType,
                                    namespacedType
                                }),
                            }),
                        }))
                    }
                }
            };

            Helpers.StructDiff(root, other);
        }
Exemplo n.º 9
0
 public XamlIlAstTransformationContext CreateTransformationContext(XamlIlDocument doc, bool strict)
 => new XamlIlAstTransformationContext(_configuration, doc.NamespaceAliases, strict);
Exemplo n.º 10
0
        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");
        }