예제 #1
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
        {
            var typeNode    = node.Properties[new XmlName("", "Type")] as IElementNode;
            var typeTypeRef = context.TypeExtensions[typeNode];
            var n           = node.CollectionItems.Count;

            var instructions = new List <Instruction>();

            instructions.Add(Instruction.Create(OpCodes.Ldc_I4, n));
            instructions.Add(Instruction.Create(OpCodes.Newarr, typeTypeRef));

            memberRef = typeTypeRef.MakeArrayType();
            for (var i = 0; i < n; i++)
            {
                var vardef = context.Variables[node.CollectionItems[i] as IElementNode];
                if (typeTypeRef.IsValueType)
                {
                    instructions.Add(Instruction.Create(OpCodes.Dup));
                    instructions.Add(Instruction.Create(OpCodes.Ldc_I4, i));
                    instructions.Add(Instruction.Create(OpCodes.Ldelema, typeTypeRef));
                    instructions.Add(Instruction.Create(OpCodes.Ldloc, vardef));
                    if (vardef.VariableType == module.TypeSystem.Object)
                    {
                        instructions.Add(Instruction.Create(OpCodes.Unbox_Any, module.ImportReference(typeTypeRef)));
                    }
                    instructions.Add(Instruction.Create(OpCodes.Stobj, typeTypeRef));
                }
                else
                {
                    instructions.Add(Instruction.Create(OpCodes.Dup));
                    instructions.Add(Instruction.Create(OpCodes.Ldc_I4, i));
                    instructions.Add(Instruction.Create(OpCodes.Ldloc, vardef));
                    instructions.Add(Instruction.Create(OpCodes.Stelem_Ref));
                }
            }
            return(instructions);
        }
예제 #2
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
        {
            memberRef = module.ImportReference(("mscorlib", "System", "Type"));
            INode typeNameNode;

            var name = new XmlName("", "TypeName");

            if (!node.Properties.TryGetValue(name, out typeNameNode) && node.CollectionItems.Any())
            {
                typeNameNode = node.CollectionItems[0];
            }

            var valueNode = typeNameNode as ValueNode;

            if (valueNode == null)
            {
                throw new XamlParseException("TypeName isn't set.", node as XmlLineInfo);
            }

            if (!node.Properties.ContainsKey(name))
            {
                node.Properties[name] = typeNameNode;
                node.CollectionItems.Clear();
            }

            var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode, XmlTypeExtensions.ModeOfGetType.Both));

            context.TypeExtensions[node] = typeref ?? throw new XamlParseException($"Can't resolve type `{valueNode.Value}'.", node as IXmlLineInfo);

            return(new List <Instruction> {
                Create(Ldtoken, module.ImportReference(typeref)),
                Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
                                                          methodName: "GetTypeFromHandle",
                                                          parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
        public static bool MatchXArguments(this MethodDefinition methodDef, ElementNode enode, TypeReference declaringTypeRef, ModuleDefinition module, ILContext context)
        {
            if (!enode.Properties.ContainsKey(XmlName.xArguments))
            {
                return(!methodDef.HasParameters);
            }

            var arguments = new List <INode>();
            var node      = enode.Properties[XmlName.xArguments] as ElementNode;

            if (node != null)
            {
                arguments.Add(node);
            }

            var list = enode.Properties[XmlName.xArguments] as ListNode;

            if (list != null)
            {
                foreach (var n in list.CollectionItems)
                {
                    arguments.Add(n);
                }
            }

            if (methodDef.Parameters.Count != arguments.Count)
            {
                return(false);
            }

            for (var i = 0; i < methodDef.Parameters.Count; i++)
            {
                var paramType = methodDef.Parameters[i].ParameterType;
                var genParam  = paramType as GenericParameter;
                if (genParam != null)
                {
                    var index = genParam.DeclaringType.GenericParameters.IndexOf(genParam);
                    paramType = (declaringTypeRef as GenericInstanceType).GenericArguments[index];
                }
                var argType = context.Variables [arguments [i] as IElementNode].VariableType;
                if (!argType.InheritsFromOrImplements(paramType))
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #4
0
        bool TryCoreCompile(MethodDefinition initComp, ILRootNode rootnode, out Exception exception)
        {
            try
            {
                var body   = new MethodBody(initComp);
                var module = body.Method.Module;
                var type   = initComp.DeclaringType;

                MethodDefinition constructorOfRemoveEventsType;
                TypeDefinition   typeOfRemoveEvents = CreateTypeForRemoveEvents(type, out constructorOfRemoveEventsType);

                var field = type.GetOrCreateField("___Info_Of_RemoveEvent___", FieldAttributes.Private, typeOfRemoveEvents);

                body.InitLocals = true;
                var il = body.GetILProcessor();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Newobj, constructorOfRemoveEventsType);
                il.Emit(OpCodes.Stfld, field);

                var resourcePath = GetPathForType(module, type);

                il.Emit(Nop);

                List <Instruction> insOfAddEvent = new List <Instruction>();

                var visitorContext = new ILContext(il, body, insOfAddEvent, module);

                rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null);
                rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null);
                rootnode.Accept(new PruneIgnoredNodesVisitor(), null);
                rootnode.Accept(new CreateObjectVisitor(visitorContext), null);

                Set(visitorContext, visitorContext.Variables[rootnode], "IsCreateByXaml", new ValueNode("true", rootnode.NamespaceResolver), null);

                rootnode.Accept(new SetNamescopesAndRegisterNamesVisitor(visitorContext), null);
                rootnode.Accept(new SetFieldVisitor(visitorContext), null);
                rootnode.Accept(new SetResourcesVisitor(visitorContext), null);
                rootnode.Accept(new SetPropertiesVisitor(visitorContext, true), null);

                AddInsOfRemoveEvent(il, visitorContext.InsOfAddEvent, typeOfRemoveEvents);

                il.Emit(Ret);
                initComp.Body = body;
                exception     = null;
                return(true);
            }
            catch (Exception e)
            {
                XamlParseException xamlParseException = e as XamlParseException;
                if (null != xamlParseException)
                {
                    XamlParseException ret = new XamlParseException(xamlParseException.Message + "\n" + ReferencePath, xamlParseException.XmlInfo, xamlParseException.InnerException);
                    exception = ret;
                }
                else
                {
                    exception = e;
                }

                return(false);
            }
        }