internal static void AddIncludeMetadata(CodeAttributeDeclarationCollection metadata, StructMapping mapping, Type type) { if (mapping.IsAnonymousType) { return; } for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) { CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(type.FullName); attribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(derived.TypeDesc.FullName))); metadata.Add(attribute); AddIncludeMetadata(metadata, derived, type); } }
internal void SetSequence() { if (TypeDesc.IsRoot) { return; } StructMapping start = this; // find first mapping that does not have the sequence set while (!start.BaseMapping.IsSequence && start.BaseMapping != null && !start.BaseMapping.TypeDesc.IsRoot) { start = start.BaseMapping; } start.IsSequence = true; for (StructMapping derived = start.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) { derived.SetSequence(); } }
private XmlQualifiedName ExportStructMapping(StructMapping mapping, string ns) { if (mapping.TypeDesc.IsRoot) { return(ExportRootMapping(mapping)); } XmlSchemaComplexType type = (XmlSchemaComplexType)_types[mapping]; if (type == null) { if (!mapping.IncludeInSchema) { throw new InvalidOperationException(string.Format(ResXml.XmlSoapCannotIncludeInSchema, mapping.TypeDesc.Name)); } CheckForDuplicateType(mapping.TypeName, mapping.Namespace); type = new XmlSchemaComplexType(); type.Name = mapping.TypeName; _types.Add(mapping, type); AddSchemaItem(type, mapping.Namespace, ns); type.IsAbstract = mapping.TypeDesc.IsAbstract; if (mapping.BaseMapping != null && mapping.BaseMapping.IncludeInSchema) { XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension(); extension.BaseTypeName = ExportStructMapping(mapping.BaseMapping, mapping.Namespace); XmlSchemaComplexContent model = new XmlSchemaComplexContent(); model.Content = extension; type.ContentModel = model; } ExportTypeMembers(type, mapping.Members, mapping.Namespace); ExportDerivedMappings(mapping); } else { AddSchemaImport(mapping.Namespace, ns); } return(new XmlQualifiedName(type.Name, mapping.Namespace)); }
private StructMapping ImportStructType(XmlSchemaComplexType type, string typeNs, bool excludeFromImport) { if (type.Name == null) { XmlSchemaElement element = (XmlSchemaElement)type.Parent; XmlQualifiedName parentType = XmlSchemas.GetParentName(element); throw new InvalidOperationException(string.Format(ResXml.XmlInvalidSchemaElementType, parentType.Name, parentType.Namespace, element.Name)); } TypeDesc baseTypeDesc = null; Mapping baseMapping = null; if (!type.DerivedFrom.IsEmpty) { baseMapping = ImportType(type.DerivedFrom, excludeFromImport); if (baseMapping is StructMapping) { baseTypeDesc = ((StructMapping)baseMapping).TypeDesc; } else { baseMapping = null; } } if (baseMapping == null) { baseMapping = GetRootMapping(); } Mapping previousMapping = (Mapping)ImportedMappings[type]; if (previousMapping != null) { return((StructMapping)previousMapping); } string typeName = GenerateUniqueTypeName(Accessor.UnescapeName(type.Name)); StructMapping structMapping = new StructMapping(); structMapping.IsReference = Schemas.IsReference(type); TypeFlags flags = TypeFlags.Reference; if (type.IsAbstract) { flags |= TypeFlags.Abstract; } structMapping.TypeDesc = new TypeDesc(typeName, typeName, TypeKind.Struct, baseTypeDesc, flags); structMapping.Namespace = typeNs; structMapping.TypeName = type.Name; structMapping.BaseMapping = (StructMapping)baseMapping; ImportedMappings.Add(type, structMapping); if (excludeFromImport) { structMapping.IncludeInSchema = false; } CodeIdentifiers members = new CodeIdentifiers(); members.AddReserved(typeName); AddReservedIdentifiersForDataBinding(members); structMapping.Members = ImportTypeMembers(type, typeNs, members); Scope.AddTypeMapping(structMapping); ImportDerivedTypes(new XmlQualifiedName(type.Name, typeNs)); return(structMapping); }
private CodeTypeDeclaration ExportStruct(StructMapping mapping) { if (mapping.TypeDesc.IsRoot) { ExportRoot(mapping, typeof(SoapIncludeAttribute)); return(null); } if (!mapping.IncludeInSchema) { return(null); } string className = mapping.TypeDesc.Name; string baseName = mapping.TypeDesc.BaseTypeDesc == null ? string.Empty : mapping.TypeDesc.BaseTypeDesc.Name; CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className); codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes); codeClass.Comments.Add(new CodeCommentStatement(ResXml.XmlRemarks, true)); CodeNamespace.Types.Add(codeClass); if (baseName != null && baseName.Length > 0) { codeClass.BaseTypes.Add(baseName); } else { AddPropertyChangedNotifier(codeClass); } codeClass.TypeAttributes |= TypeAttributes.Public; if (mapping.TypeDesc.IsAbstract) { codeClass.TypeAttributes |= TypeAttributes.Abstract; } CodeExporter.AddIncludeMetadata(codeClass.CustomAttributes, mapping, typeof(SoapIncludeAttribute)); if (GenerateProperties) { for (int i = 0; i < mapping.Members.Length; i++) { ExportProperty(codeClass, mapping.Members[i], mapping.Scope); } } else { for (int i = 0; i < mapping.Members.Length; i++) { ExportMember(codeClass, mapping.Members[i]); } } for (int i = 0; i < mapping.Members.Length; i++) { EnsureTypesExported(mapping.Members[i].Elements, null); } if (mapping.BaseMapping != null) { ExportType(mapping.BaseMapping); } ExportDerivedStructs(mapping); CodeGenerator.ValidateIdentifiers(codeClass); return(codeClass); }
private bool InitializeStructMembers(StructMapping mapping, StructModel model, RecursionLimiter limiter) { if (mapping.IsFullyInitialized) { return(true); } if (model.TypeDesc.BaseTypeDesc != null) { StructMapping baseMapping = ImportStructLikeMapping((StructModel)_modelScope.GetTypeModel(model.Type.GetTypeInfo().BaseType, false), limiter); // check to see if the import of the baseMapping was deffered int baseIndex = limiter.DeferredWorkItems.IndexOf(mapping.BaseMapping); if (baseIndex < 0) { mapping.BaseMapping = baseMapping; } else { // the import of the baseMapping was deffered, make sure that the derived mappings is deffered as well if (!limiter.DeferredWorkItems.Contains(mapping)) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); } // make sure that baseMapping get processed before the derived int top = limiter.DeferredWorkItems.Count - 1; if (baseIndex < top) { ImportStructWorkItem baseMappingWorkItem = limiter.DeferredWorkItems[baseIndex]; limiter.DeferredWorkItems[baseIndex] = limiter.DeferredWorkItems[top]; limiter.DeferredWorkItems[top] = baseMappingWorkItem; } return(false); } } ArrayList members = new ArrayList(); foreach (MemberInfo memberInfo in model.GetMemberInfos()) { if (memberInfo is FieldInfo || memberInfo is PropertyInfo) { continue; } SoapAttributes memberAttrs = GetAttributes(memberInfo); if (memberAttrs.SoapIgnore) { continue; } FieldModel fieldModel = model.GetFieldModel(memberInfo); if (fieldModel == null) { continue; } MemberMapping member = ImportFieldMapping(fieldModel, memberAttrs, mapping.Namespace, limiter); if (member == null) { continue; } if (!member.TypeDesc.IsPrimitive && !member.TypeDesc.IsEnum && !member.TypeDesc.IsOptionalValue) { if (model.TypeDesc.IsValueType) { throw new NotSupportedException(string.Format(ResXml.XmlRpcRefsInValueType, model.TypeDesc.FullName)); } if (member.TypeDesc.IsValueType) { throw new NotSupportedException(string.Format(ResXml.XmlRpcNestedValueType, member.TypeDesc.FullName)); } } if (mapping.BaseMapping != null) { if (mapping.BaseMapping.Declares(member, mapping.TypeName)) { continue; } } members.Add(member); } mapping.Members = (MemberMapping[])members.ToArray(typeof(MemberMapping)); if (mapping.BaseMapping == null) { mapping.BaseMapping = GetRootMapping(); } IncludeTypes(model.Type, limiter); return(true); }
private StructMapping ImportStructLikeMapping(StructModel model, RecursionLimiter limiter) { if (model.TypeDesc.Kind == TypeKind.Root) { return(GetRootMapping()); } SoapAttributes a = GetAttributes(model.Type); string typeNs = _defaultNs; if (a.SoapType != null && a.SoapType.Namespace != null) { typeNs = a.SoapType.Namespace; } string typeName = XsdTypeName(model.Type, a, model.TypeDesc.Name); typeName = XmlConvert.EncodeLocalName(typeName); StructMapping mapping = (StructMapping)GetTypeMapping(typeName, typeNs, model.TypeDesc); if (mapping == null) { mapping = new StructMapping(); mapping.IsSoap = true; mapping.TypeDesc = model.TypeDesc; mapping.Namespace = typeNs; mapping.TypeName = typeName; if (a.SoapType != null) { mapping.IncludeInSchema = a.SoapType.IncludeInSchema; } _typeScope.AddTypeMapping(mapping); _types.Add(typeName, typeNs, mapping); if (limiter.IsExceededLimit) { limiter.DeferredWorkItems.Add(new ImportStructWorkItem(model, mapping)); return(mapping); } limiter.Depth++; InitializeStructMembers(mapping, model, limiter); while (limiter.DeferredWorkItems.Count > 0) { int index = limiter.DeferredWorkItems.Count - 1; ImportStructWorkItem item = limiter.DeferredWorkItems[index]; if (InitializeStructMembers(item.Mapping, item.Model, limiter)) { // // if InitializeStructMembers returns true, then there were *no* chages to the DeferredWorkItems // #if DEBUG // use exception in the place of Debug.Assert to avoid throwing asserts from a server process such as aspnet_ewp.exe if (index != limiter.DeferredWorkItems.Count - 1) { throw new InvalidOperationException(string.Format(ResXml.XmlInternalErrorDetails, "DeferredWorkItems.Count have changed")); } if (item != limiter.DeferredWorkItems[index]) { throw new InvalidOperationException(string.Format(ResXml.XmlInternalErrorDetails, "DeferredWorkItems.Top have changed")); } #endif // Remove the last work item limiter.DeferredWorkItems.RemoveAt(index); } } limiter.Depth--; } return(mapping); }
private CodeTypeDeclaration ExportStruct(StructMapping mapping) { if (mapping.TypeDesc.IsRoot) { ExportRoot(mapping, typeof(XmlIncludeAttribute)); return(null); } string className = mapping.TypeDesc.Name; string baseName = mapping.TypeDesc.BaseTypeDesc == null || mapping.TypeDesc.BaseTypeDesc.IsRoot ? string.Empty : mapping.TypeDesc.BaseTypeDesc.FullName; CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className); codeClass.IsPartial = CodeProvider.Supports(GeneratorSupport.PartialTypes); codeClass.Comments.Add(new CodeCommentStatement(ResXml.XmlRemarks, true)); CodeNamespace.Types.Add(codeClass); CodeConstructor ctor = new CodeConstructor(); ctor.Attributes = (ctor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; codeClass.Members.Add(ctor); if (mapping.TypeDesc.IsAbstract) { ctor.Attributes |= MemberAttributes.Abstract; } if (baseName != null && baseName.Length > 0) { codeClass.BaseTypes.Add(baseName); } else { AddPropertyChangedNotifier(codeClass); } codeClass.TypeAttributes |= TypeAttributes.Public; if (mapping.TypeDesc.IsAbstract) { codeClass.TypeAttributes |= TypeAttributes.Abstract; } AddIncludeMetadata(codeClass.CustomAttributes, mapping, typeof(XmlIncludeAttribute)); if (mapping.IsSequence) { int generatedSequence = 0; for (int i = 0; i < mapping.Members.Length; i++) { MemberMapping member = mapping.Members[i]; if (member.IsParticle && member.SequenceId < 0) { member.SequenceId = generatedSequence++; } } } if (GenerateProperties) { for (int i = 0; i < mapping.Members.Length; i++) { ExportProperty(codeClass, mapping.Members[i], mapping.Namespace, mapping.Scope, ctor); } } else { for (int i = 0; i < mapping.Members.Length; i++) { ExportMember(codeClass, mapping.Members[i], mapping.Namespace, ctor); } } for (int i = 0; i < mapping.Members.Length; i++) { if (mapping.Members[i].Xmlns != null) { continue; } EnsureTypesExported(mapping.Members[i].Elements, mapping.Namespace); EnsureTypesExported(mapping.Members[i].Attribute, mapping.Namespace); EnsureTypesExported(mapping.Members[i].Text, mapping.Namespace); } if (mapping.BaseMapping != null) { ExportType(mapping.BaseMapping, null, mapping.Namespace, null, false); } ExportDerivedStructs(mapping); CodeGenerator.ValidateIdentifiers(codeClass); if (ctor.Statements.Count == 0) { codeClass.Members.Remove(ctor); } return(codeClass); }
internal abstract void ExportDerivedStructs(StructMapping mapping);