private GetLocal ( string name ) : LocalBuilder | ||
name | string | |
return | LocalBuilder |
string GenerateLiteralMembersElement(XmlMembersMapping xmlMembersMapping) { ElementAccessor element = xmlMembersMapping.Accessor; MemberMapping[] mappings = ((MembersMapping)element.Mapping).Members; bool hasWrapperElement = ((MembersMapping)element.Mapping).HasWrapperElement; string methodName = NextMethodName(element.Name); ilg = new CodeGenerator(this.typeBuilder); ilg.BeginMethod( typeof(object[]), methodName, CodeGenerator.EmptyTypeArray, CodeGenerator.EmptyStringArray, CodeGenerator.PublicMethodAttributes ); ilg.Load(null); ilg.Stloc(ilg.ReturnLocal); MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod( "get_Reader", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod( "MoveToContent", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToContent); ilg.Pop(); LocalBuilder localP = ilg.DeclareLocal(typeof(object[]), "p"); ilg.NewArray(typeof(object), mappings.Length); ilg.Stloc(localP); InitializeValueTypes("p", mappings); int wrapperLoopIndex = 0; if (hasWrapperElement) { wrapperLoopIndex = WriteWhileNotLoopStart(); WriteIsStartTag(element.Name, element.Form == XmlSchemaForm.Qualified ? element.Namespace : ""); } Member anyText = null; Member anyElement = null; Member anyAttribute = null; ArrayList membersList = new ArrayList(); ArrayList textOrArrayMembersList = new ArrayList(); ArrayList attributeMembersList = new ArrayList(); for (int i = 0; i < mappings.Length; i++) { MemberMapping mapping = mappings[i]; string source = "p[" + i.ToString(CultureInfo.InvariantCulture) + "]"; string arraySource = source; if (mapping.Xmlns != null) { arraySource = "((" + mapping.TypeDesc.CSharpName + ")" + source + ")"; } string choiceSource = GetChoiceIdentifierSource(mappings, mapping); Member member = new Member(this, source, arraySource, "a", i, mapping, choiceSource); Member anyMember = new Member(this, source, null, "a", i, mapping, choiceSource); if (!mapping.IsSequence) member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]"; if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite) { string nameSpecified = mapping.Name + "Specified"; for (int j = 0; j < mappings.Length; j++) { if (mappings[j].Name == nameSpecified) { member.CheckSpecifiedSource = "p[" + j.ToString(CultureInfo.InvariantCulture) + "]"; break; } } } bool foundAnyElement = false; if (mapping.Text != null) anyText = anyMember; if (mapping.Attribute != null && mapping.Attribute.Any) anyAttribute = anyMember; if (mapping.Attribute != null || mapping.Xmlns != null) attributeMembersList.Add(member); else if (mapping.Text != null) textOrArrayMembersList.Add(member); if (!mapping.IsSequence) { for (int j = 0; j < mapping.Elements.Length; j++) { if (mapping.Elements[j].Any && mapping.Elements[j].Name.Length == 0) { anyElement = anyMember; if (mapping.Attribute == null && mapping.Text == null) textOrArrayMembersList.Add(anyMember); foundAnyElement = true; break; } } } if (mapping.Attribute != null || mapping.Text != null || foundAnyElement) membersList.Add(anyMember); else if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) { membersList.Add(anyMember); textOrArrayMembersList.Add(anyMember); } else { if (mapping.TypeDesc.IsArrayLike && !mapping.TypeDesc.IsArray) member.ParamsReadSource = null; // collection membersList.Add(member); } } Member[] members = (Member[])membersList.ToArray(typeof(Member)); Member[] textOrArrayMembers = (Member[])textOrArrayMembersList.ToArray(typeof(Member)); if (members.Length > 0 && members[0].Mapping.IsReturnValue) { MethodInfo XmlSerializationReader_set_IsReturnValue = typeof(XmlSerializationReader).GetMethod( "set_IsReturnValue", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(Boolean) }, null ); ilg.Ldarg(0); ilg.Ldc(true); ilg.Call(XmlSerializationReader_set_IsReturnValue); } WriteParamsRead(mappings.Length); if (attributeMembersList.Count > 0) { Member[] attributeMembers = (Member[])attributeMembersList.ToArray(typeof(Member)); WriteMemberBegin(attributeMembers); WriteAttributes(attributeMembers, anyAttribute, "UnknownNode", localP); WriteMemberEnd(attributeMembers); MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod( "MoveToElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToElement); ilg.Pop(); } WriteMemberBegin(textOrArrayMembers); if (hasWrapperElement) { MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod( "get_IsEmptyElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_get_IsEmptyElement); ilg.If(); { MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod( "Skip", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_Skip); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToContent); ilg.Pop(); ilg.WhileContinue(); } ilg.EndIf(); MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod( "ReadStartElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_ReadStartElement); } if (IsSequence(members)) { ilg.Ldc(0); ilg.Stloc(typeof(Int32), "state"); } int loopIndex = WriteWhileNotLoopStart(); string unknownNode = "UnknownNode((object)p, " + ExpectedElements(members) + ");"; WriteMemberElements(members, unknownNode, unknownNode, anyElement, anyText); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToContent); ilg.Pop(); WriteWhileLoopEnd(loopIndex); WriteMemberEnd(textOrArrayMembers); if (hasWrapperElement) { MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod( "ReadEndElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_ReadEndElement); WriteUnknownNode("UnknownNode", "null", element, true); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToContent); ilg.Pop(); WriteWhileLoopEnd(wrapperLoopIndex); } ilg.Ldloc(ilg.GetLocal("p")); ilg.EndMethod(); return methodName; }
void WriteLiteralStructMethod(StructMapping structMapping) { string methodName = (string)MethodNames[structMapping]; string typeName = structMapping.TypeDesc.CSharpName; ilg = new CodeGenerator(this.typeBuilder); List<Type> argTypes = new List<Type>(); List<string> argNames = new List<string>(); if (structMapping.TypeDesc.IsNullable) { argTypes.Add(typeof(Boolean)); argNames.Add("isNullable"); } argTypes.Add(typeof(Boolean)); argNames.Add("checkType"); ilg.BeginMethod( structMapping.TypeDesc.Type, GetMethodBuilder(methodName), argTypes.ToArray(), argNames.ToArray(), CodeGenerator.PrivateMethodAttributes); LocalBuilder locXsiType = ilg.DeclareLocal(typeof(XmlQualifiedName), "xsiType"); LocalBuilder locIsNull = ilg.DeclareLocal(typeof(Boolean), "isNull"); MethodInfo XmlSerializationReader_GetXsiType = typeof(XmlSerializationReader).GetMethod( "GetXsiType", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); MethodInfo XmlSerializationReader_ReadNull = typeof(XmlSerializationReader).GetMethod( "ReadNull", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); Label labelTrue = ilg.DefineLabel(); Label labelEnd = ilg.DefineLabel(); ilg.Ldarg("checkType"); ilg.Brtrue(labelTrue); ilg.Load(null); ilg.Br_S(labelEnd); ilg.MarkLabel(labelTrue); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_GetXsiType); ilg.MarkLabel(labelEnd); ilg.Stloc(locXsiType); ilg.Ldc(false); ilg.Stloc(locIsNull); if (structMapping.TypeDesc.IsNullable) { ilg.Ldarg("isNullable"); ilg.If(); { ilg.Ldarg(0); ilg.Call(XmlSerializationReader_ReadNull); ilg.Stloc(locIsNull); } ilg.EndIf(); } ilg.Ldarg("checkType"); ilg.If(); // if (checkType) if (structMapping.TypeDesc.IsRoot) { ilg.Ldloc(locIsNull); ilg.If(); ilg.Ldloc(locXsiType); ilg.Load(null); ilg.If(Cmp.NotEqualTo); MethodInfo XmlSerializationReader_ReadTypedNull = typeof(XmlSerializationReader).GetMethod( "ReadTypedNull", CodeGenerator.InstanceBindingFlags, null, new Type[] { locXsiType.LocalType }, null ); ilg.Ldarg(0); ilg.Ldloc(locXsiType); ilg.Call(XmlSerializationReader_ReadTypedNull); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); ilg.Else(); if (structMapping.TypeDesc.IsValueType) { throw CodeGenerator.NotSupported("Arg_NeverValueType"); } else { ilg.Load(null); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } ilg.EndIf(); // if (xsiType != null) ilg.EndIf(); // if (isNull) } ilg.Ldloc(typeof(XmlQualifiedName), "xsiType"); ilg.Load(null); ilg.Ceq(); if (!structMapping.TypeDesc.IsRoot) { labelTrue = ilg.DefineLabel(); labelEnd = ilg.DefineLabel(); // xsiType == null ilg.Brtrue(labelTrue); WriteQNameEqual("xsiType", structMapping.TypeName, structMapping.Namespace); // Bool result for WriteQNameEqual is on the stack ilg.Br_S(labelEnd); ilg.MarkLabel(labelTrue); ilg.Ldc(true); ilg.MarkLabel(labelEnd); } ilg.If(); // if (xsiType == null if (structMapping.TypeDesc.IsRoot) { ConstructorInfo XmlQualifiedName_ctor = typeof(XmlQualifiedName).GetConstructor( CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(String), typeof(String) }, null ); MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod( "ReadTypedPrimitive", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(XmlQualifiedName) }, null ); ilg.Ldarg(0); ilg.Ldstr(Soap.UrType); ilg.Ldstr(XmlSchema.Namespace); ilg.New(XmlQualifiedName_ctor); ilg.Call(XmlSerializationReader_ReadTypedPrimitive); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } WriteDerivedTypes(structMapping, !structMapping.TypeDesc.IsRoot, typeName); if (structMapping.TypeDesc.IsRoot) WriteEnumAndArrayTypes(); ilg.Else(); // if (xsiType == null if (structMapping.TypeDesc.IsRoot) { MethodInfo XmlSerializationReader_ReadTypedPrimitive = typeof(XmlSerializationReader).GetMethod( "ReadTypedPrimitive", CodeGenerator.InstanceBindingFlags, null, new Type[] { locXsiType.LocalType }, null ); ilg.Ldarg(0); ilg.Ldloc(locXsiType); ilg.Call(XmlSerializationReader_ReadTypedPrimitive); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } else { MethodInfo XmlSerializationReader_CreateUnknownTypeException = typeof(XmlSerializationReader).GetMethod( "CreateUnknownTypeException", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(XmlQualifiedName) }, null ); ilg.Ldarg(0); ilg.Ldloc(locXsiType); ilg.Call(XmlSerializationReader_CreateUnknownTypeException); ilg.Throw(); } ilg.EndIf(); // if (xsiType == null ilg.EndIf(); // checkType if (structMapping.TypeDesc.IsNullable) { ilg.Ldloc(typeof(bool), "isNull"); ilg.If(); { ilg.Load(null); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); } ilg.EndIf(); } if (structMapping.TypeDesc.IsAbstract) { MethodInfo XmlSerializationReader_CreateAbstractTypeException = typeof(XmlSerializationReader).GetMethod( "CreateAbstractTypeException", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(String), typeof(String) }, null ); ilg.Ldarg(0); ilg.Ldstr(structMapping.TypeName); ilg.Ldstr(structMapping.Namespace); ilg.Call(XmlSerializationReader_CreateAbstractTypeException); ilg.Throw(); } else { if (structMapping.TypeDesc.Type != null && typeof(XmlSchemaObject).IsAssignableFrom(structMapping.TypeDesc.Type)) { MethodInfo XmlSerializationReader_set_DecodeName = typeof(XmlSerializationReader).GetMethod( "set_DecodeName", CodeGenerator.InstanceBindingFlags, null, new Type[] { typeof(Boolean) }, null ); ilg.Ldarg(0); ilg.Ldc(false); ilg.Call(XmlSerializationReader_set_DecodeName); } WriteCreateMapping(structMapping, "o"); LocalBuilder oLoc = ilg.GetLocal("o"); // this method populates the memberInfos dictionary based on the structMapping MemberMapping[] mappings = TypeScope.GetSettableMembers(structMapping, memberInfos); Member anyText = null; Member anyElement = null; Member anyAttribute = null; bool isSequence = structMapping.HasExplicitSequence(); ArrayList arraysToDeclareList = new ArrayList(mappings.Length); ArrayList arraysToSetList = new ArrayList(mappings.Length); ArrayList allMembersList = new ArrayList(mappings.Length); for (int i = 0; i < mappings.Length; i++) { MemberMapping mapping = mappings[i]; CodeIdentifier.CheckValidIdentifier(mapping.Name); string source = RaCodeGen.GetStringForMember("o", mapping.Name, structMapping.TypeDesc); Member member = new Member(this, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc)); if (!mapping.IsSequence) member.ParamsReadSource = "paramsRead[" + i.ToString(CultureInfo.InvariantCulture) + "]"; member.IsNullable = mapping.TypeDesc.IsNullable; if (mapping.CheckSpecified == SpecifiedAccessor.ReadWrite) member.CheckSpecifiedSource = RaCodeGen.GetStringForMember("o", mapping.Name + "Specified", structMapping.TypeDesc); if (mapping.Text != null) anyText = member; if (mapping.Attribute != null && mapping.Attribute.Any) anyAttribute = member; if (!isSequence) { // find anyElement if present. for (int j = 0; j < mapping.Elements.Length; j++) { if (mapping.Elements[j].Any && (mapping.Elements[j].Name == null || mapping.Elements[j].Name.Length == 0)) { anyElement = member; break; } } } else if (mapping.IsParticle && !mapping.IsSequence) { StructMapping declaringMapping; structMapping.FindDeclaringMapping(mapping, out declaringMapping, structMapping.TypeName); throw new InvalidOperationException(Res.GetString(Res.XmlSequenceHierarchy, structMapping.TypeDesc.FullName, mapping.Name, declaringMapping.TypeDesc.FullName, "Order")); } if (mapping.Attribute == null && mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping) { Member arrayMember = new Member(this, source, source, "a", i, mapping, GetChoiceIdentifierSource(mapping, "o", structMapping.TypeDesc)); arrayMember.CheckSpecifiedSource = member.CheckSpecifiedSource; allMembersList.Add(arrayMember); } else { allMembersList.Add(member); } if (mapping.TypeDesc.IsArrayLike) { arraysToDeclareList.Add(member); if (mapping.TypeDesc.IsArrayLike && !(mapping.Elements.Length == 1 && mapping.Elements[0].Mapping is ArrayMapping)) { member.ParamsReadSource = null; // flat arrays -- don't want to count params read. if (member != anyText && member != anyElement) { arraysToSetList.Add(member); } } else if (!mapping.TypeDesc.IsArray) { member.ParamsReadSource = null; // collection } } } if (anyElement != null) arraysToSetList.Add(anyElement); if (anyText != null && anyText != anyElement) arraysToSetList.Add(anyText); Member[] arraysToDeclare = (Member[])arraysToDeclareList.ToArray(typeof(Member)); Member[] arraysToSet = (Member[])arraysToSetList.ToArray(typeof(Member)); Member[] allMembers = (Member[])allMembersList.ToArray(typeof(Member)); WriteMemberBegin(arraysToDeclare); WriteParamsRead(mappings.Length); WriteAttributes(allMembers, anyAttribute, "UnknownNode", oLoc); if (anyAttribute != null) WriteMemberEnd(arraysToDeclare); MethodInfo XmlSerializationReader_get_Reader = typeof(XmlSerializationReader).GetMethod( "get_Reader", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); MethodInfo XmlReader_MoveToElement = typeof(XmlReader).GetMethod( "MoveToElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToElement); ilg.Pop(); MethodInfo XmlReader_get_IsEmptyElement = typeof(XmlReader).GetMethod( "get_IsEmptyElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_get_IsEmptyElement); ilg.If(); MethodInfo XmlReader_Skip = typeof(XmlReader).GetMethod( "Skip", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_Skip); WriteMemberEnd(arraysToSet); ilg.Ldloc(oLoc); ilg.Stloc(ilg.ReturnLocal); ilg.Br(ilg.ReturnLabel); ilg.EndIf(); MethodInfo XmlReader_ReadStartElement = typeof(XmlReader).GetMethod( "ReadStartElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_ReadStartElement); if (IsSequence(allMembers)) { ilg.Ldc(0); ilg.Stloc(typeof(Int32), "state"); } int loopIndex = WriteWhileNotLoopStart(); string unknownNode = "UnknownNode((object)o, " + ExpectedElements(allMembers) + ");"; WriteMemberElements(allMembers, unknownNode, unknownNode, anyElement, anyText); MethodInfo XmlReader_MoveToContent = typeof(XmlReader).GetMethod( "MoveToContent", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_get_Reader); ilg.Call(XmlReader_MoveToContent); ilg.Pop(); WriteWhileLoopEnd(loopIndex); WriteMemberEnd(arraysToSet); MethodInfo XmlSerializationReader_ReadEndElement = typeof(XmlSerializationReader).GetMethod( "ReadEndElement", CodeGenerator.InstanceBindingFlags, null, CodeGenerator.EmptyTypeArray, null ); ilg.Ldarg(0); ilg.Call(XmlSerializationReader_ReadEndElement); ilg.Ldloc(structMapping.TypeDesc.Type, "o"); ilg.Stloc(ilg.ReturnLocal); } ilg.MarkLabel(ilg.ReturnLabel); ilg.Ldloc(ilg.ReturnLocal); ilg.EndMethod(); }