| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.Runtime.Serialization
- {
- using System;
- using System.CodeDom;
- using System.CodeDom.Compiler;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Globalization;
- using System.Reflection;
- using System.Security;
- using System.Text;
- using System.Xml;
- using System.Xml.Schema;
- using DataContractDictionary = System.Collections.Generic.Dictionary<System.Xml.XmlQualifiedName, DataContract>;
- class CodeExporter
- {
- DataContractSet dataContractSet;
- CodeCompileUnit codeCompileUnit;
- ImportOptions options;
- Dictionary<string, string> namespaces;
- Dictionary<string, string> clrNamespaces;
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- static readonly string wildcardNamespaceMapping = "*";
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- static readonly string typeNameFieldName = "typeName";
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- static readonly object codeUserDataActualTypeKey = new object();
- [Fx.Tag.SecurityNote(Miscellaneous = "RequiresReview - Static fields are marked SecurityCritical or readonly to prevent"
- + " data from being modified or leaked to other components in appdomain.")]
- static readonly object surrogateDataKey = typeof(IDataContractSurrogate);
- const int MaxIdentifierLength = 511;
- internal CodeExporter(DataContractSet dataContractSet, ImportOptions options, CodeCompileUnit codeCompileUnit)
- {
- this.dataContractSet = dataContractSet;
- this.codeCompileUnit = codeCompileUnit;
- AddReferencedAssembly(Assembly.GetExecutingAssembly());
- this.options = options;
- this.namespaces = new Dictionary<string, string>();
- this.clrNamespaces = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
- // Update namespace tables for DataContract(s) that are already processed
- foreach (KeyValuePair<XmlQualifiedName, DataContract> pair in dataContractSet)
- {
- DataContract dataContract = pair.Value;
- if (!(dataContract.IsBuiltInDataContract || dataContract is CollectionDataContract))
- {
- ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
- if (contractCodeDomInfo.IsProcessed && !contractCodeDomInfo.UsesWildcardNamespace)
- {
- string clrNamespace = contractCodeDomInfo.ClrNamespace;
- if (clrNamespace != null && !this.clrNamespaces.ContainsKey(clrNamespace))
- {
- this.clrNamespaces.Add(clrNamespace, dataContract.StableName.Namespace);
- this.namespaces.Add(dataContract.StableName.Namespace, clrNamespace);
- }
- }
- }
- }
- // Copy options.Namespaces to namespace tables
- if (this.options != null)
- {
- foreach (KeyValuePair<string, string> pair in options.Namespaces)
- {
- string dataContractNamespace = pair.Key;
- string clrNamespace = pair.Value;
- if (clrNamespace == null)
- clrNamespace = String.Empty;
- string currentDataContractNamespace;
- if (this.clrNamespaces.TryGetValue(clrNamespace, out currentDataContractNamespace))
- {
- if (dataContractNamespace != currentDataContractNamespace)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CLRNamespaceMappedMultipleTimes, currentDataContractNamespace, dataContractNamespace, clrNamespace)));
- }
- else
- this.clrNamespaces.Add(clrNamespace, dataContractNamespace);
- string currentClrNamespace;
- if (this.namespaces.TryGetValue(dataContractNamespace, out currentClrNamespace))
- {
- if (clrNamespace != currentClrNamespace)
- {
- this.namespaces.Remove(dataContractNamespace);
- this.namespaces.Add(dataContractNamespace, clrNamespace);
- }
- }
- else
- this.namespaces.Add(dataContractNamespace, clrNamespace);
- }
- }
- // Update namespace tables for pre-existing namespaces in CodeCompileUnit
- foreach (CodeNamespace codeNS in codeCompileUnit.Namespaces)
- {
- string ns = codeNS.Name ?? string.Empty;
- if (!this.clrNamespaces.ContainsKey(ns))
- {
- this.clrNamespaces.Add(ns, null);
- }
- if (ns.Length == 0)
- {
- foreach (CodeTypeDeclaration codeTypeDecl in codeNS.Types)
- {
- AddGlobalTypeName(codeTypeDecl.Name);
- }
- }
- }
- }
- void AddReferencedAssembly(Assembly assembly)
- {
- string assemblyName = System.IO.Path.GetFileName(assembly.Location);
- bool alreadyExisting = false;
- foreach (string existingName in this.codeCompileUnit.ReferencedAssemblies)
- {
- if (String.Compare(existingName, assemblyName, StringComparison.OrdinalIgnoreCase) == 0)
- {
- alreadyExisting = true;
- break;
- }
- }
- if (!alreadyExisting)
- this.codeCompileUnit.ReferencedAssemblies.Add(assemblyName);
- }
- bool GenerateSerializableTypes
- {
- get { return (options == null) ? false : options.GenerateSerializable; }
- }
- bool GenerateInternalTypes
- {
- get { return (options == null) ? false : options.GenerateInternal; }
- }
- bool EnableDataBinding
- {
- get { return (options == null) ? false : options.EnableDataBinding; }
- }
- CodeDomProvider CodeProvider
- {
- get { return (options == null) ? null : options.CodeProvider; }
- }
- bool SupportsDeclareEvents
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.DeclareEvents); }
- }
- bool SupportsDeclareValueTypes
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.DeclareValueTypes); }
- }
- bool SupportsGenericTypeReference
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.GenericTypeReference); }
- }
- bool SupportsAssemblyAttributes
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.AssemblyAttributes); }
- }
- bool SupportsPartialTypes
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.PartialTypes); }
- }
- bool SupportsNestedTypes
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.Supports(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? true : CodeProvider.Supports(GeneratorSupport.NestedTypes); }
- }
- string FileExtension
- {
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeProvider.FileExtension property that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- get { return (CodeProvider == null) ? String.Empty : CodeProvider.FileExtension; }
- }
- Dictionary<string, string> Namespaces
- {
- get { return namespaces; }
- }
- Dictionary<string, string> ClrNamespaces
- {
- get { return clrNamespaces; }
- }
- bool TryGetReferencedType(XmlQualifiedName stableName, DataContract dataContract, out Type type)
- {
- if (dataContract == null)
- {
- if (dataContractSet.TryGetReferencedCollectionType(stableName, dataContract, out type))
- return true;
- if (dataContractSet.TryGetReferencedType(stableName, dataContract, out type))
- {
- // enforce that collection types only be specified via ReferencedCollectionTypes
- if (CollectionDataContract.IsCollection(type))
- {
- type = null;
- return false;
- }
- return true;
- }
- return false;
- }
- else if (dataContract is CollectionDataContract)
- return dataContractSet.TryGetReferencedCollectionType(stableName, dataContract, out type);
- else
- {
- XmlDataContract xmlDataContract = dataContract as XmlDataContract;
- if (xmlDataContract != null && xmlDataContract.IsAnonymous)
- {
- stableName = SchemaImporter.ImportActualType(xmlDataContract.XsdType.Annotation, stableName, dataContract.StableName);
- }
- return dataContractSet.TryGetReferencedType(stableName, dataContract, out type);
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the System.CodeDom.Compiler.CodeGenerator.ValidateIdentifiers(..) method that has a LinkDemand for FullTrust.")]
- [SecurityCritical]
- internal void Export()
- {
- try
- {
- foreach (KeyValuePair<XmlQualifiedName, DataContract> pair in dataContractSet)
- {
- DataContract dataContract = pair.Value;
- if (dataContract.IsBuiltInDataContract)
- continue;
- ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
- if (!contractCodeDomInfo.IsProcessed)
- {
- if (dataContract is ClassDataContract)
- {
- ClassDataContract classDataContract = (ClassDataContract)dataContract;
- if (classDataContract.IsISerializable)
- ExportISerializableDataContract(classDataContract, contractCodeDomInfo);
- else
- ExportClassDataContractHierarchy(classDataContract.StableName, classDataContract, contractCodeDomInfo, new Dictionary<XmlQualifiedName, object>());
- }
- else if (dataContract is CollectionDataContract)
- ExportCollectionDataContract((CollectionDataContract)dataContract, contractCodeDomInfo);
- else if (dataContract is EnumDataContract)
- ExportEnumDataContract((EnumDataContract)dataContract, contractCodeDomInfo);
- else if (dataContract is XmlDataContract)
- ExportXmlDataContract((XmlDataContract)dataContract, contractCodeDomInfo);
- else
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.UnexpectedContractType, DataContract.GetClrTypeFullName(dataContract.GetType()), DataContract.GetClrTypeFullName(dataContract.UnderlyingType))));
- contractCodeDomInfo.IsProcessed = true;
- }
- }
- if (dataContractSet.DataContractSurrogate != null)
- {
- CodeNamespace[] namespaces = new CodeNamespace[codeCompileUnit.Namespaces.Count];
- codeCompileUnit.Namespaces.CopyTo(namespaces, 0);
- foreach (CodeNamespace codeNamespace in namespaces)
- InvokeProcessImportedType(codeNamespace.Types);
- }
- }
- finally
- {
- System.CodeDom.Compiler.CodeGenerator.ValidateIdentifiers(codeCompileUnit);
- }
- }
- void ExportClassDataContractHierarchy(XmlQualifiedName typeName, ClassDataContract classContract, ContractCodeDomInfo contractCodeDomInfo, Dictionary<XmlQualifiedName, object> contractNamesInHierarchy)
- {
- if (contractNamesInHierarchy.ContainsKey(classContract.StableName))
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeCannotBeImported, typeName.Name, typeName.Namespace, SR.GetString(SR.CircularTypeReference, classContract.StableName.Name, classContract.StableName.Namespace))));
- contractNamesInHierarchy.Add(classContract.StableName, null);
- ClassDataContract baseContract = classContract.BaseContract;
- if (baseContract != null)
- {
- ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(baseContract);
- if (!baseContractCodeDomInfo.IsProcessed)
- {
- ExportClassDataContractHierarchy(typeName, baseContract, baseContractCodeDomInfo, contractNamesInHierarchy);
- baseContractCodeDomInfo.IsProcessed = true;
- }
- }
- ExportClassDataContract(classContract, contractCodeDomInfo);
- }
- void InvokeProcessImportedType(CollectionBase collection)
- {
- object[] objects = new object[collection.Count];
- ((ICollection)collection).CopyTo(objects, 0);
- foreach (object obj in objects)
- {
- CodeTypeDeclaration codeTypeDeclaration = obj as CodeTypeDeclaration;
- if (codeTypeDeclaration == null)
- continue;
- CodeTypeDeclaration newCodeTypeDeclaration = DataContractSurrogateCaller.ProcessImportedType(
- dataContractSet.DataContractSurrogate,
- codeTypeDeclaration,
- codeCompileUnit);
- if (newCodeTypeDeclaration != codeTypeDeclaration)
- {
- ((IList)collection).Remove(codeTypeDeclaration);
- if (newCodeTypeDeclaration != null)
- ((IList)collection).Add(newCodeTypeDeclaration);
- }
- if (newCodeTypeDeclaration != null)
- InvokeProcessImportedType(newCodeTypeDeclaration.Members);
- }
- }
- internal CodeTypeReference GetCodeTypeReference(DataContract dataContract)
- {
- if (dataContract.IsBuiltInDataContract)
- return GetCodeTypeReference(dataContract.UnderlyingType);
- ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
- GenerateType(dataContract, contractCodeDomInfo);
- return contractCodeDomInfo.TypeReference;
- }
- CodeTypeReference GetCodeTypeReference(Type type)
- {
- AddReferencedAssembly(type.Assembly);
- return new CodeTypeReference(type);
- }
- internal CodeTypeReference GetElementTypeReference(DataContract dataContract, bool isElementTypeNullable)
- {
- CodeTypeReference elementTypeReference = GetCodeTypeReference(dataContract);
- if (dataContract.IsValueType && isElementTypeNullable)
- elementTypeReference = WrapNullable(elementTypeReference);
- return elementTypeReference;
- }
- XmlQualifiedName GenericListName
- {
- get { return DataContract.GetStableName(Globals.TypeOfListGeneric); }
- }
- CollectionDataContract GenericListContract
- {
- get { return dataContractSet.GetDataContract(Globals.TypeOfListGeneric) as CollectionDataContract; }
- }
- XmlQualifiedName GenericDictionaryName
- {
- get { return DataContract.GetStableName(Globals.TypeOfDictionaryGeneric); }
- }
- CollectionDataContract GenericDictionaryContract
- {
- get { return dataContractSet.GetDataContract(Globals.TypeOfDictionaryGeneric) as CollectionDataContract; }
- }
- ContractCodeDomInfo GetContractCodeDomInfo(DataContract dataContract)
- {
- ContractCodeDomInfo contractCodeDomInfo = dataContractSet.GetContractCodeDomInfo(dataContract);
- if (contractCodeDomInfo == null)
- {
- contractCodeDomInfo = new ContractCodeDomInfo();
- dataContractSet.SetContractCodeDomInfo(dataContract, contractCodeDomInfo);
- }
- return contractCodeDomInfo;
- }
- void GenerateType(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- if (!contractCodeDomInfo.IsProcessed)
- {
- CodeTypeReference referencedType = GetReferencedType(dataContract);
- if (referencedType != null)
- {
- contractCodeDomInfo.TypeReference = referencedType;
- contractCodeDomInfo.ReferencedTypeExists = true;
- }
- else
- {
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- if (type == null)
- {
- string clrNamespace = GetClrNamespace(dataContract, contractCodeDomInfo);
- CodeNamespace ns = GetCodeNamespace(clrNamespace, dataContract.StableName.Namespace, contractCodeDomInfo);
- type = GetNestedType(dataContract, contractCodeDomInfo);
- if (type == null)
- {
- string typeName = XmlConvert.DecodeName(dataContract.StableName.Name);
- typeName = GetClrIdentifier(typeName, Globals.DefaultTypeName);
- if (NamespaceContainsType(ns, typeName) || GlobalTypeNameConflicts(clrNamespace, typeName))
- {
- for (int i = 1;; i++)
- {
- string uniqueName = AppendToValidClrIdentifier(typeName, i.ToString(NumberFormatInfo.InvariantInfo));
- if (!NamespaceContainsType(ns, uniqueName) && !GlobalTypeNameConflicts(clrNamespace, uniqueName))
- {
- typeName = uniqueName;
- break;
- }
- if (i == Int32.MaxValue)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, typeName)));
- }
- }
- type = CreateTypeDeclaration(typeName, dataContract);
- ns.Types.Add(type);
- if (string.IsNullOrEmpty(clrNamespace))
- {
- AddGlobalTypeName(typeName);
- }
- contractCodeDomInfo.TypeReference = new CodeTypeReference((clrNamespace == null || clrNamespace.Length == 0) ? typeName : clrNamespace + "." + typeName);
- if (GenerateInternalTypes)
- type.TypeAttributes = TypeAttributes.NotPublic;
- else
- type.TypeAttributes = TypeAttributes.Public;
- }
- if (dataContractSet.DataContractSurrogate != null)
- type.UserData.Add(surrogateDataKey, dataContractSet.GetSurrogateData(dataContract));
- contractCodeDomInfo.TypeDeclaration = type;
- }
- }
- }
- }
- CodeTypeDeclaration GetNestedType(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- if (!SupportsNestedTypes)
- return null;
- string originalName = dataContract.StableName.Name;
- int nestedTypeIndex = originalName.LastIndexOf('.');
- if (nestedTypeIndex <= 0)
- return null;
- string containingTypeName = originalName.Substring(0, nestedTypeIndex);
- DataContract containingDataContract = dataContractSet[new XmlQualifiedName(containingTypeName, dataContract.StableName.Namespace)];
- if (containingDataContract == null)
- return null;
- string nestedTypeName = XmlConvert.DecodeName(originalName.Substring(nestedTypeIndex + 1));
- nestedTypeName = GetClrIdentifier(nestedTypeName, Globals.DefaultTypeName);
- ContractCodeDomInfo containingContractCodeDomInfo = GetContractCodeDomInfo(containingDataContract);
- GenerateType(containingDataContract, containingContractCodeDomInfo);
- if (containingContractCodeDomInfo.ReferencedTypeExists)
- return null;
- CodeTypeDeclaration containingType = containingContractCodeDomInfo.TypeDeclaration;
- if (TypeContainsNestedType(containingType, nestedTypeName))
- {
- for (int i = 1;; i++)
- {
- string uniqueName = AppendToValidClrIdentifier(nestedTypeName, i.ToString(NumberFormatInfo.InvariantInfo));
- if (!TypeContainsNestedType(containingType, uniqueName))
- {
- nestedTypeName = uniqueName;
- break;
- }
- }
- }
- CodeTypeDeclaration type = CreateTypeDeclaration(nestedTypeName, dataContract);
- containingType.Members.Add(type);
- contractCodeDomInfo.TypeReference = new CodeTypeReference(containingContractCodeDomInfo.TypeReference.BaseType + "+" + nestedTypeName);
- if (GenerateInternalTypes)
- type.TypeAttributes = TypeAttributes.NestedAssembly;
- else
- type.TypeAttributes = TypeAttributes.NestedPublic;
- return type;
- }
- static CodeTypeDeclaration CreateTypeDeclaration(string typeName, DataContract dataContract)
- {
- CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(typeName);
- CodeAttributeDeclaration debuggerStepThroughAttribute = new CodeAttributeDeclaration(typeof(System.Diagnostics.DebuggerStepThroughAttribute).FullName);
- CodeAttributeDeclaration generatedCodeAttribute = new CodeAttributeDeclaration(typeof(GeneratedCodeAttribute).FullName);
- AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();
- generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Name)));
- generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Version.ToString())));
- // System.Diagnostics.DebuggerStepThroughAttribute not allowed on enums
- // ensure that the attribute is only generated on types that are not enums
- EnumDataContract enumDataContract = dataContract as EnumDataContract;
- if (enumDataContract == null)
- {
- typeDecl.CustomAttributes.Add(debuggerStepThroughAttribute);
- }
- typeDecl.CustomAttributes.Add(generatedCodeAttribute);
- return typeDecl;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal XmlDataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- CodeTypeReference GetReferencedType(DataContract dataContract)
- {
- Type type = null;
- CodeTypeReference typeReference = GetSurrogatedTypeReference(dataContract);
- if (typeReference != null)
- return typeReference;
- if (TryGetReferencedType(dataContract.StableName, dataContract, out type)
- && !type.IsGenericTypeDefinition && !type.ContainsGenericParameters)
- {
- if (dataContract is XmlDataContract)
- {
- if (Globals.TypeOfIXmlSerializable.IsAssignableFrom(type))
- {
- XmlDataContract xmlContract = (XmlDataContract)dataContract;
- if (xmlContract.IsTypeDefinedOnImport)
- {
- if (!xmlContract.Equals(dataContractSet.GetDataContract(type)))
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch, type.AssemblyQualifiedName, dataContract.StableName.Name, dataContract.StableName.Namespace)));
- }
- else
- {
- xmlContract.IsValueType = type.IsValueType;
- xmlContract.IsTypeDefinedOnImport = true;
- }
- return GetCodeTypeReference(type);
- }
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.TypeMustBeIXmlSerializable, DataContract.GetClrTypeFullName(type), DataContract.GetClrTypeFullName(Globals.TypeOfIXmlSerializable), dataContract.StableName.Name, dataContract.StableName.Namespace)));
- }
- DataContract referencedContract = dataContractSet.GetDataContract(type);
- if (referencedContract.Equals(dataContract))
- {
- typeReference = GetCodeTypeReference(type);
- typeReference.UserData.Add(codeUserDataActualTypeKey, type);
- return typeReference;
- }
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch, type.AssemblyQualifiedName, dataContract.StableName.Name, dataContract.StableName.Namespace)));
- }
- else if (dataContract.GenericInfo != null)
- {
- DataContract referencedContract;
- XmlQualifiedName genericStableName = dataContract.GenericInfo.GetExpandedStableName();
- if (genericStableName != dataContract.StableName)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.GenericTypeNameMismatch, dataContract.StableName.Name, dataContract.StableName.Namespace, genericStableName.Name, genericStableName.Namespace)));
- typeReference = GetReferencedGenericType(dataContract.GenericInfo, out referencedContract);
- if (referencedContract != null && !referencedContract.Equals(dataContract))
- {
- type = (Type)typeReference.UserData[codeUserDataActualTypeKey];
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedTypeDoesNotMatch,
- type.AssemblyQualifiedName,
- referencedContract.StableName.Name,
- referencedContract.StableName.Namespace)));
- }
- return typeReference;
- }
- return GetReferencedCollectionType(dataContract as CollectionDataContract);
- }
- CodeTypeReference GetReferencedCollectionType(CollectionDataContract collectionContract)
- {
- if (collectionContract == null)
- return null;
- if (HasDefaultCollectionNames(collectionContract))
- {
- CodeTypeReference typeReference;
- if (!TryGetReferencedDictionaryType(collectionContract, out typeReference))
- {
- DataContract itemContract = collectionContract.ItemContract;
- if (collectionContract.IsDictionary)
- {
- GenerateKeyValueType(itemContract as ClassDataContract);
- }
- bool isItemTypeNullable = collectionContract.IsItemTypeNullable;
- if (!TryGetReferencedListType(itemContract, isItemTypeNullable, out typeReference))
- typeReference = new CodeTypeReference(GetElementTypeReference(itemContract, isItemTypeNullable), 1);
- }
- return typeReference;
- }
- return null;
- }
- bool HasDefaultCollectionNames(CollectionDataContract collectionContract)
- {
- DataContract itemContract = collectionContract.ItemContract;
- if (collectionContract.ItemName != itemContract.StableName.Name)
- return false;
- if (collectionContract.IsDictionary &&
- (collectionContract.KeyName != Globals.KeyLocalName || collectionContract.ValueName != Globals.ValueLocalName))
- return false;
- XmlQualifiedName expectedType = itemContract.GetArrayTypeName(collectionContract.IsItemTypeNullable);
- return (collectionContract.StableName.Name == expectedType.Name && collectionContract.StableName.Namespace == expectedType.Namespace);
- }
- bool TryGetReferencedDictionaryType(CollectionDataContract collectionContract, out CodeTypeReference typeReference)
- {
- // Check if it is a dictionary and use referenced dictionary type if present
- if (collectionContract.IsDictionary
- && SupportsGenericTypeReference)
- {
- Type type;
- if (!TryGetReferencedType(GenericDictionaryName, GenericDictionaryContract, out type))
- type = Globals.TypeOfDictionaryGeneric;
- ClassDataContract itemContract = collectionContract.ItemContract as ClassDataContract;
- DataMember keyMember = itemContract.Members[0];
- DataMember valueMember = itemContract.Members[1];
- CodeTypeReference keyTypeReference = GetElementTypeReference(keyMember.MemberTypeContract, keyMember.IsNullable);
- CodeTypeReference valueTypeReference = GetElementTypeReference(valueMember.MemberTypeContract, valueMember.IsNullable);
- if (keyTypeReference != null && valueTypeReference != null)
- {
- typeReference = GetCodeTypeReference(type);
- typeReference.TypeArguments.Add(keyTypeReference);
- typeReference.TypeArguments.Add(valueTypeReference);
- return true;
- }
- }
- typeReference = null;
- return false;
- }
- bool TryGetReferencedListType(DataContract itemContract, bool isItemTypeNullable, out CodeTypeReference typeReference)
- {
- Type type;
- if (SupportsGenericTypeReference && TryGetReferencedType(GenericListName, GenericListContract, out type))
- {
- typeReference = GetCodeTypeReference(type);
- typeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable));
- return true;
- }
- typeReference = null;
- return false;
- }
- CodeTypeReference GetSurrogatedTypeReference(DataContract dataContract)
- {
- IDataContractSurrogate dataContractSurrogate = this.dataContractSet.DataContractSurrogate;
- if (dataContractSurrogate != null)
- {
- Type type = DataContractSurrogateCaller.GetReferencedTypeOnImport(
- dataContractSurrogate,
- dataContract.StableName.Name,
- dataContract.StableName.Namespace,
- dataContractSet.GetSurrogateData(dataContract));
- if (type != null)
- {
- CodeTypeReference typeReference = GetCodeTypeReference(type);
- typeReference.UserData.Add(codeUserDataActualTypeKey, type);
- return typeReference;
- }
- }
- return null;
- }
- CodeTypeReference GetReferencedGenericType(GenericInfo genInfo, out DataContract dataContract)
- {
- dataContract = null;
- if (!SupportsGenericTypeReference)
- return null;
- Type type;
- if (!TryGetReferencedType(genInfo.StableName, null, out type))
- {
- if (genInfo.Parameters != null)
- return null;
- dataContract = dataContractSet[genInfo.StableName];
- if (dataContract == null)
- return null;
- if (dataContract.GenericInfo != null)
- return null;
- return GetCodeTypeReference(dataContract);
- }
- bool enableStructureCheck = (type != Globals.TypeOfNullable);
- CodeTypeReference typeReference = GetCodeTypeReference(type);
- typeReference.UserData.Add(codeUserDataActualTypeKey, type);
- if (genInfo.Parameters != null)
- {
- DataContract[] paramContracts = new DataContract[genInfo.Parameters.Count];
- for (int i = 0; i < genInfo.Parameters.Count; i++)
- {
- GenericInfo paramInfo = genInfo.Parameters[i];
- XmlQualifiedName stableName = paramInfo.GetExpandedStableName();
- DataContract paramContract = dataContractSet[stableName];
- CodeTypeReference paramTypeReference;
- bool isParamValueType;
- if (paramContract != null)
- {
- paramTypeReference = GetCodeTypeReference(paramContract);
- isParamValueType = paramContract.IsValueType;
- }
- else
- {
- paramTypeReference = GetReferencedGenericType(paramInfo, out paramContract);
- isParamValueType = (paramTypeReference != null && paramTypeReference.ArrayRank == 0); // only value type information we can get from CodeTypeReference
- }
- paramContracts[i] = paramContract;
- if (paramContract == null)
- enableStructureCheck = false;
- if (paramTypeReference == null)
- return null;
- if (type == Globals.TypeOfNullable && !isParamValueType)
- return paramTypeReference;
- else
- typeReference.TypeArguments.Add(paramTypeReference);
- }
- if (enableStructureCheck)
- dataContract = DataContract.GetDataContract(type).BindGenericParameters(paramContracts, new Dictionary<DataContract, DataContract>());
- }
- return typeReference;
- }
- bool NamespaceContainsType(CodeNamespace ns, string typeName)
- {
- foreach (CodeTypeDeclaration type in ns.Types)
- {
- if (String.Compare(typeName, type.Name, StringComparison.OrdinalIgnoreCase) == 0)
- return true;
- }
- return false;
- }
- bool GlobalTypeNameConflicts(string clrNamespace, string typeName)
- {
- return (string.IsNullOrEmpty(clrNamespace) && this.clrNamespaces.ContainsKey(typeName));
- }
- void AddGlobalTypeName(string typeName)
- {
- if (!this.clrNamespaces.ContainsKey(typeName))
- {
- this.clrNamespaces.Add(typeName, null);
- }
- }
- bool TypeContainsNestedType(CodeTypeDeclaration containingType, string typeName)
- {
- foreach (CodeTypeMember member in containingType.Members)
- {
- if (member is CodeTypeDeclaration)
- {
- if (String.Compare(typeName, ((CodeTypeDeclaration)member).Name, StringComparison.OrdinalIgnoreCase) == 0)
- return true;
- }
- }
- return false;
- }
- string GetNameForAttribute(string name)
- {
- string decodedName = XmlConvert.DecodeName(name);
- if (string.CompareOrdinal(name, decodedName) == 0)
- return name;
- string reencodedName = DataContract.EncodeLocalName(decodedName);
- return (string.CompareOrdinal(name, reencodedName) == 0) ? decodedName : name;
- }
- void AddSerializableAttribute(bool generateSerializable, CodeTypeDeclaration type, ContractCodeDomInfo contractCodeDomInfo)
- {
- if (generateSerializable)
- {
- type.CustomAttributes.Add(SerializableAttribute);
- AddImportStatement(Globals.TypeOfSerializableAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- }
- }
- void ExportClassDataContract(ClassDataContract classDataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- GenerateType(classDataContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return;
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- if (SupportsPartialTypes)
- type.IsPartial = true;
- if (classDataContract.IsValueType && SupportsDeclareValueTypes)
- type.IsStruct = true;
- else
- type.IsClass = true;
- string dataContractName = GetNameForAttribute(classDataContract.StableName.Name);
- CodeAttributeDeclaration dataContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataContractAttribute));
- dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName)));
- dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(classDataContract.StableName.Namespace)));
- if (classDataContract.IsReference != Globals.DefaultIsReference)
- dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsReferenceProperty, new CodePrimitiveExpression(classDataContract.IsReference)));
- type.CustomAttributes.Add(dataContractAttribute);
- AddImportStatement(Globals.TypeOfDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- AddSerializableAttribute(GenerateSerializableTypes, type, contractCodeDomInfo);
- AddKnownTypes(classDataContract, contractCodeDomInfo);
- bool raisePropertyChanged = EnableDataBinding && SupportsDeclareEvents;
- if (classDataContract.BaseContract == null)
- {
- if (!type.IsStruct)
- type.BaseTypes.Add(Globals.TypeOfObject);
- AddExtensionData(contractCodeDomInfo);
- AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
- }
- else
- {
- ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(classDataContract.BaseContract);
- Fx.Assert(baseContractCodeDomInfo.IsProcessed, "Cannot generate code for type if code for base type has not been generated");
- type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference);
- AddBaseMemberNames(baseContractCodeDomInfo, contractCodeDomInfo);
- if (baseContractCodeDomInfo.ReferencedTypeExists)
- {
- Type actualType = (Type)baseContractCodeDomInfo.TypeReference.UserData[codeUserDataActualTypeKey];
- ThrowIfReferencedBaseTypeSealed(actualType, classDataContract);
- if (!Globals.TypeOfIExtensibleDataObject.IsAssignableFrom(actualType))
- AddExtensionData(contractCodeDomInfo);
- if (!Globals.TypeOfIPropertyChange.IsAssignableFrom(actualType))
- {
- AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
- }
- else
- {
- raisePropertyChanged = false;
- }
- }
- }
- if (classDataContract.Members != null)
- {
- for (int i = 0; i < classDataContract.Members.Count; i++)
- {
- DataMember dataMember = classDataContract.Members[i];
- CodeTypeReference memberType = GetElementTypeReference(dataMember.MemberTypeContract,
- (dataMember.IsNullable && dataMember.MemberTypeContract.IsValueType));
- string dataMemberName = GetNameForAttribute(dataMember.Name);
- string propertyName = GetMemberName(dataMemberName, contractCodeDomInfo);
- string fieldName = GetMemberName(AppendToValidClrIdentifier(propertyName, Globals.DefaultFieldSuffix), contractCodeDomInfo);
- CodeMemberField field = new CodeMemberField();
- field.Type = memberType;
- field.Name = fieldName;
- field.Attributes = MemberAttributes.Private;
- CodeMemberProperty property = CreateProperty(memberType, propertyName, fieldName, dataMember.MemberTypeContract.IsValueType && SupportsDeclareValueTypes, raisePropertyChanged);
- if (dataContractSet.DataContractSurrogate != null)
- property.UserData.Add(surrogateDataKey, dataContractSet.GetSurrogateData(dataMember));
- CodeAttributeDeclaration dataMemberAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataMemberAttribute));
- if (dataMemberName != property.Name)
- dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataMemberName)));
- if (dataMember.IsRequired != Globals.DefaultIsRequired)
- dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsRequiredProperty, new CodePrimitiveExpression(dataMember.IsRequired)));
- if (dataMember.EmitDefaultValue != Globals.DefaultEmitDefaultValue)
- dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.EmitDefaultValueProperty, new CodePrimitiveExpression(dataMember.EmitDefaultValue)));
- if (dataMember.Order != Globals.DefaultOrder)
- dataMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.OrderProperty, new CodePrimitiveExpression(dataMember.Order)));
- property.CustomAttributes.Add(dataMemberAttribute);
- if (GenerateSerializableTypes && !dataMember.IsRequired)
- {
- CodeAttributeDeclaration optionalFieldAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfOptionalFieldAttribute));
- field.CustomAttributes.Add(optionalFieldAttribute);
- }
- type.Members.Add(field);
- type.Members.Add(property);
- }
- }
- }
- bool CanDeclareAssemblyAttribute(ContractCodeDomInfo contractCodeDomInfo)
- {
- return SupportsAssemblyAttributes && !contractCodeDomInfo.UsesWildcardNamespace;
- }
- bool NeedsExplicitNamespace(string dataContractNamespace, string clrNamespace)
- {
- return (DataContract.GetDefaultStableNamespace(clrNamespace) != dataContractNamespace);
- }
- internal ICollection<CodeTypeReference> GetKnownTypeReferences(DataContract dataContract)
- {
- DataContractDictionary knownTypeDictionary = GetKnownTypeContracts(dataContract);
- if (knownTypeDictionary == null)
- return null;
- ICollection<DataContract> knownTypeContracts = knownTypeDictionary.Values;
- if (knownTypeContracts == null || knownTypeContracts.Count == 0)
- return null;
- List<CodeTypeReference> knownTypeReferences = new List<CodeTypeReference>();
- foreach (DataContract knownTypeContract in knownTypeContracts)
- {
- knownTypeReferences.Add(GetCodeTypeReference(knownTypeContract));
- }
- return knownTypeReferences;
- }
- DataContractDictionary GetKnownTypeContracts(DataContract dataContract)
- {
- if (dataContractSet.KnownTypesForObject != null && SchemaImporter.IsObjectContract(dataContract))
- {
- return dataContractSet.KnownTypesForObject;
- }
- else if (dataContract is ClassDataContract)
- {
- ContractCodeDomInfo contractCodeDomInfo = GetContractCodeDomInfo(dataContract);
- if (!contractCodeDomInfo.IsProcessed)
- GenerateType(dataContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return GetKnownTypeContracts((ClassDataContract)dataContract, new Dictionary<DataContract, object>());
- }
- return null;
- }
- DataContractDictionary GetKnownTypeContracts(ClassDataContract dataContract, Dictionary<DataContract, object> handledContracts)
- {
- if (handledContracts.ContainsKey(dataContract))
- return dataContract.KnownDataContracts;
- handledContracts.Add(dataContract, null);
- if (dataContract.Members != null)
- {
- bool objectMemberHandled = false;
- foreach (DataMember dataMember in dataContract.Members)
- {
- DataContract memberContract = dataMember.MemberTypeContract;
- if (!objectMemberHandled && dataContractSet.KnownTypesForObject != null && SchemaImporter.IsObjectContract(memberContract))
- {
- AddKnownTypeContracts(dataContract, dataContractSet.KnownTypesForObject);
- objectMemberHandled = true;
- }
- else if (memberContract is ClassDataContract)
- {
- ContractCodeDomInfo memberCodeDomInfo = GetContractCodeDomInfo(memberContract);
- if (!memberCodeDomInfo.IsProcessed)
- GenerateType(memberContract, memberCodeDomInfo);
- if (memberCodeDomInfo.ReferencedTypeExists)
- {
- AddKnownTypeContracts(dataContract, GetKnownTypeContracts((ClassDataContract)memberContract, handledContracts));
- }
- }
- }
- }
- return dataContract.KnownDataContracts;
- }
- [Fx.Tag.SecurityNote(Critical = "Sets critical properties on internal DataContract.",
- Safe = "Called during schema import/code generation.")]
- [SecuritySafeCritical]
- void AddKnownTypeContracts(ClassDataContract dataContract, DataContractDictionary knownContracts)
- {
- if (knownContracts == null || knownContracts.Count == 0)
- return;
- if (dataContract.KnownDataContracts == null)
- dataContract.KnownDataContracts = new DataContractDictionary();
- foreach (KeyValuePair<XmlQualifiedName, DataContract> pair in knownContracts)
- {
- if (dataContract.StableName != pair.Key && !dataContract.KnownDataContracts.ContainsKey(pair.Key) && !pair.Value.IsBuiltInDataContract)
- dataContract.KnownDataContracts.Add(pair.Key, pair.Value);
- }
- }
- void AddKnownTypes(ClassDataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- DataContractDictionary knownContractDictionary = GetKnownTypeContracts(dataContract, new Dictionary<DataContract, object>());
- if (knownContractDictionary == null || knownContractDictionary.Count == 0)
- return;
- ICollection<DataContract> knownTypeContracts = knownContractDictionary.Values;
- foreach (DataContract knownTypeContract in knownTypeContracts)
- {
- CodeAttributeDeclaration knownTypeAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfKnownTypeAttribute));
- knownTypeAttribute.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(GetCodeTypeReference(knownTypeContract))));
- contractCodeDomInfo.TypeDeclaration.CustomAttributes.Add(knownTypeAttribute);
- }
- AddImportStatement(Globals.TypeOfKnownTypeAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- }
- CodeTypeReference WrapNullable(CodeTypeReference memberType)
- {
- if (!SupportsGenericTypeReference)
- return memberType;
- CodeTypeReference nullableOfMemberType = GetCodeTypeReference(Globals.TypeOfNullable);
- nullableOfMemberType.TypeArguments.Add(memberType);
- return nullableOfMemberType;
- }
- void AddExtensionData(ContractCodeDomInfo contractCodeDomInfo)
- {
- if (contractCodeDomInfo != null && contractCodeDomInfo.TypeDeclaration != null)
- {
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfIExtensibleDataObject));
- CodeMemberField extensionDataObjectField = ExtensionDataObjectField;
- if (GenerateSerializableTypes)
- {
- CodeAttributeDeclaration nonSerializedAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfNonSerializedAttribute));
- extensionDataObjectField.CustomAttributes.Add(nonSerializedAttribute);
- }
- type.Members.Add(extensionDataObjectField);
- contractCodeDomInfo.GetMemberNames().Add(extensionDataObjectField.Name, null);
- CodeMemberProperty extensionDataObjectProperty = ExtensionDataObjectProperty;
- type.Members.Add(extensionDataObjectProperty);
- contractCodeDomInfo.GetMemberNames().Add(extensionDataObjectProperty.Name, null);
- }
- }
- void AddPropertyChangedNotifier(ContractCodeDomInfo contractCodeDomInfo, bool isValueType)
- {
- if (EnableDataBinding && SupportsDeclareEvents && contractCodeDomInfo != null && contractCodeDomInfo.TypeDeclaration != null)
- {
- CodeTypeDeclaration codeTypeDeclaration = contractCodeDomInfo.TypeDeclaration;
- codeTypeDeclaration.BaseTypes.Add(CodeTypeIPropertyChange);
- CodeMemberEvent memberEvent = PropertyChangedEvent;
- codeTypeDeclaration.Members.Add(memberEvent);
- CodeMemberMethod raisePropertyChangedEventMethod = RaisePropertyChangedEventMethod;
- if (!isValueType)
- raisePropertyChangedEventMethod.Attributes |= MemberAttributes.Family;
- codeTypeDeclaration.Members.Add(raisePropertyChangedEventMethod);
- contractCodeDomInfo.GetMemberNames().Add(memberEvent.Name, null);
- contractCodeDomInfo.GetMemberNames().Add(raisePropertyChangedEventMethod.Name, null);
- }
- }
- void ThrowIfReferencedBaseTypeSealed(Type baseType, DataContract dataContract)
- {
- if (baseType.IsSealed)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotDeriveFromSealedReferenceType, dataContract.StableName.Name, dataContract.StableName.Namespace, DataContract.GetClrTypeFullName(baseType))));
- }
- void ExportEnumDataContract(EnumDataContract enumDataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- GenerateType(enumDataContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return;
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- type.IsEnum = true;
- type.BaseTypes.Add(EnumDataContract.GetBaseType(enumDataContract.BaseContractName));
- if (enumDataContract.IsFlags)
- {
- type.CustomAttributes.Add(new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfFlagsAttribute)));
- AddImportStatement(Globals.TypeOfFlagsAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- }
- string dataContractName = GetNameForAttribute(enumDataContract.StableName.Name);
- CodeAttributeDeclaration dataContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfDataContractAttribute));
- dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName)));
- dataContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(enumDataContract.StableName.Namespace)));
- type.CustomAttributes.Add(dataContractAttribute);
- AddImportStatement(Globals.TypeOfDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- if (enumDataContract.Members != null)
- {
- for (int i = 0; i < enumDataContract.Members.Count; i++)
- {
- string stringValue = enumDataContract.Members[i].Name;
- long longValue = enumDataContract.Values[i];
- CodeMemberField enumMember = new CodeMemberField();
- if (enumDataContract.IsULong)
- enumMember.InitExpression = new CodeSnippetExpression(enumDataContract.GetStringFromEnumValue(longValue));
- else
- enumMember.InitExpression = new CodePrimitiveExpression(longValue);
- enumMember.Name = GetMemberName(stringValue, contractCodeDomInfo);
- CodeAttributeDeclaration enumMemberAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfEnumMemberAttribute));
- if (enumMember.Name != stringValue)
- enumMemberAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ValueProperty, new CodePrimitiveExpression(stringValue)));
- enumMember.CustomAttributes.Add(enumMemberAttribute);
- type.Members.Add(enumMember);
- }
- }
- }
- void ExportISerializableDataContract(ClassDataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- GenerateType(dataContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return;
- if (DataContract.GetDefaultStableNamespace(contractCodeDomInfo.ClrNamespace) != dataContract.StableName.Namespace)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidClrNamespaceGeneratedForISerializable, dataContract.StableName.Name, dataContract.StableName.Namespace, DataContract.GetDataContractNamespaceFromUri(dataContract.StableName.Namespace), contractCodeDomInfo.ClrNamespace)));
- string dataContractName = GetNameForAttribute(dataContract.StableName.Name);
- int nestedTypeIndex = dataContractName.LastIndexOf('.');
- string expectedName = (nestedTypeIndex <= 0 || nestedTypeIndex == dataContractName.Length - 1) ? dataContractName : dataContractName.Substring(nestedTypeIndex + 1);
- if (contractCodeDomInfo.TypeDeclaration.Name != expectedName)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.InvalidClrNameGeneratedForISerializable, dataContract.StableName.Name, dataContract.StableName.Namespace, contractCodeDomInfo.TypeDeclaration.Name)));
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- if (SupportsPartialTypes)
- type.IsPartial = true;
- if (dataContract.IsValueType && SupportsDeclareValueTypes)
- type.IsStruct = true;
- else
- type.IsClass = true;
- AddSerializableAttribute(true /*generateSerializable*/, type, contractCodeDomInfo);
- AddKnownTypes(dataContract, contractCodeDomInfo);
- if (dataContract.BaseContract == null)
- {
- if (!type.IsStruct)
- type.BaseTypes.Add(Globals.TypeOfObject);
- type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfISerializable));
- type.Members.Add(ISerializableBaseConstructor);
- type.Members.Add(SerializationInfoField);
- type.Members.Add(SerializationInfoProperty);
- type.Members.Add(GetObjectDataMethod);
- AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
- }
- else
- {
- ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(dataContract.BaseContract);
- GenerateType(dataContract.BaseContract, baseContractCodeDomInfo);
- type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference);
- if (baseContractCodeDomInfo.ReferencedTypeExists)
- {
- Type actualType = (Type)baseContractCodeDomInfo.TypeReference.UserData[codeUserDataActualTypeKey];
- ThrowIfReferencedBaseTypeSealed(actualType, dataContract);
- }
- type.Members.Add(ISerializableDerivedConstructor);
- }
- }
- void GenerateKeyValueType(ClassDataContract keyValueContract)
- {
- // Add code for KeyValue item type in the case where its usage is limited to dictionary
- // and dictionary is not found in referenced types
- if (keyValueContract != null && dataContractSet[keyValueContract.StableName] == null)
- {
- ContractCodeDomInfo contractCodeDomInfo = dataContractSet.GetContractCodeDomInfo(keyValueContract);
- if (contractCodeDomInfo == null)
- {
- contractCodeDomInfo = new ContractCodeDomInfo();
- dataContractSet.SetContractCodeDomInfo(keyValueContract, contractCodeDomInfo);
- ExportClassDataContract(keyValueContract, contractCodeDomInfo);
- contractCodeDomInfo.IsProcessed = true;
- }
- }
- }
- void ExportCollectionDataContract(CollectionDataContract collectionContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- GenerateType(collectionContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return;
- string dataContractName = GetNameForAttribute(collectionContract.StableName.Name);
- // If type name is not expected, generate collection type that derives from referenced list type and uses [CollectionDataContract]
- if (!SupportsGenericTypeReference)
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(
- SR.GetString(SR.CannotUseGenericTypeAsBase, dataContractName,
- collectionContract.StableName.Namespace)));
- DataContract itemContract = collectionContract.ItemContract;
- bool isItemTypeNullable = collectionContract.IsItemTypeNullable;
- CodeTypeReference baseTypeReference;
- bool foundDictionaryBase = TryGetReferencedDictionaryType(collectionContract, out baseTypeReference);
- if (!foundDictionaryBase)
- {
- if (collectionContract.IsDictionary)
- {
- GenerateKeyValueType(collectionContract.ItemContract as ClassDataContract);
- }
- if (!TryGetReferencedListType(itemContract, isItemTypeNullable, out baseTypeReference))
- {
- if (SupportsGenericTypeReference)
- {
- baseTypeReference = GetCodeTypeReference(Globals.TypeOfListGeneric);
- baseTypeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable));
- }
- else
- {
- string expectedTypeName = Globals.ArrayPrefix + itemContract.StableName.Name;
- string expectedTypeNs = DataContract.GetCollectionNamespace(itemContract.StableName.Namespace);
- throw System.Runtime.Serialization.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ReferencedBaseTypeDoesNotExist,
- dataContractName, collectionContract.StableName.Namespace,
- expectedTypeName, expectedTypeNs, DataContract.GetClrTypeFullName(Globals.TypeOfIListGeneric), DataContract.GetClrTypeFullName(Globals.TypeOfICollectionGeneric))));
- }
- }
- }
- CodeTypeDeclaration generatedType = contractCodeDomInfo.TypeDeclaration;
- generatedType.BaseTypes.Add(baseTypeReference);
- CodeAttributeDeclaration collectionContractAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfCollectionDataContractAttribute));
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NameProperty, new CodePrimitiveExpression(dataContractName)));
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.NamespaceProperty, new CodePrimitiveExpression(collectionContract.StableName.Namespace)));
- if (collectionContract.IsReference != Globals.DefaultIsReference)
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.IsReferenceProperty, new CodePrimitiveExpression(collectionContract.IsReference)));
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ItemNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.ItemName))));
- if (foundDictionaryBase)
- {
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.KeyNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.KeyName))));
- collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ValueNameProperty, new CodePrimitiveExpression(GetNameForAttribute(collectionContract.ValueName))));
- }
- generatedType.CustomAttributes.Add(collectionContractAttribute);
- AddImportStatement(Globals.TypeOfCollectionDataContractAttribute.Namespace, contractCodeDomInfo.CodeNamespace);
- AddSerializableAttribute(GenerateSerializableTypes, generatedType, contractCodeDomInfo);
- }
- private void ExportXmlDataContract(XmlDataContract xmlDataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- GenerateType(xmlDataContract, contractCodeDomInfo);
- if (contractCodeDomInfo.ReferencedTypeExists)
- return;
- CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
- if (SupportsPartialTypes)
- type.IsPartial = true;
- if (xmlDataContract.IsValueType)
- type.IsStruct = true;
- else
- {
- type.IsClass = true;
- type.BaseTypes.Add(Globals.TypeOfObject);
- }
- AddSerializableAttribute(GenerateSerializableTypes, type, contractCodeDomInfo);
- type.BaseTypes.Add(DataContract.GetClrTypeFullName(Globals.TypeOfIXmlSerializable));
- type.Members.Add(NodeArrayField);
- type.Members.Add(NodeArrayProperty);
- type.Members.Add(ReadXmlMethod);
- type.Members.Add(WriteXmlMethod);
- type.Members.Add(GetSchemaMethod);
- if (xmlDataContract.IsAnonymous && !xmlDataContract.HasRoot)
- {
- type.CustomAttributes.Add(new CodeAttributeDeclaration(
- DataContract.GetClrTypeFullName(Globals.TypeOfXmlSchemaProviderAttribute),
- new CodeAttributeArgument(NullReference),
- new CodeAttributeArgument(Globals.IsAnyProperty, new CodePrimitiveExpression(true)))
- );
- }
- else
- {
- type.CustomAttributes.Add(new CodeAttributeDeclaration(
- DataContract.GetClrTypeFullName(Globals.TypeOfXmlSchemaProviderAttribute),
- new CodeAttributeArgument(new CodePrimitiveExpression(Globals.ExportSchemaMethod)))
- );
- CodeMemberField typeNameField = new CodeMemberField(Globals.TypeOfXmlQualifiedName, typeNameFieldName);
- typeNameField.Attributes |= MemberAttributes.Static | MemberAttributes.Private;
- XmlQualifiedName typeName = xmlDataContract.IsAnonymous
- ? SchemaImporter.ImportActualType(xmlDataContract.XsdType.Annotation, xmlDataContract.StableName, xmlDataContract.StableName)
- : xmlDataContract.StableName;
- typeNameField.InitExpression = new CodeObjectCreateExpression(Globals.TypeOfXmlQualifiedName, new CodePrimitiveExpression(typeName.Name), new CodePrimitiveExpression(typeName.Namespace));
- type.Members.Add(typeNameField);
- type.Members.Add(GetSchemaStaticMethod);
- bool isElementNameDifferent =
- (xmlDataContract.TopLevelElementName != null && xmlDataContract.TopLevelElementName.Value != xmlDataContract.StableName.Name) ||
- (xmlDataContract.TopLevelElementNamespace != null && xmlDataContract.TopLevelElementNamespace.Value != xmlDataContract.StableName.Namespace);
- if (isElementNameDifferent || xmlDataContract.IsTopLevelElementNullable == false)
- {
- CodeAttributeDeclaration xmlRootAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfXmlRootAttribute));
- if (isElementNameDifferent)
- {
- if (xmlDataContract.TopLevelElementName != null)
- {
- xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("ElementName", new CodePrimitiveExpression(xmlDataContract.TopLevelElementName.Value)));
- }
- if (xmlDataContract.TopLevelElementNamespace != null)
- {
- xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(xmlDataContract.TopLevelElementNamespace.Value)));
- }
- }
- if (xmlDataContract.IsTopLevelElementNullable == false)
- xmlRootAttribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression(false)));
- type.CustomAttributes.Add(xmlRootAttribute);
- }
- }
- AddPropertyChangedNotifier(contractCodeDomInfo, type.IsStruct);
- }
- CodeNamespace GetCodeNamespace(string clrNamespace, string dataContractNamespace, ContractCodeDomInfo contractCodeDomInfo)
- {
- if (contractCodeDomInfo.CodeNamespace != null)
- return contractCodeDomInfo.CodeNamespace;
- CodeNamespaceCollection codeNamespaceCollection = codeCompileUnit.Namespaces;
- foreach (CodeNamespace ns in codeNamespaceCollection)
- {
- if (ns.Name == clrNamespace)
- {
- contractCodeDomInfo.CodeNamespace = ns;
- return ns;
- }
- }
- CodeNamespace codeNamespace = new CodeNamespace(clrNamespace);
- codeNamespaceCollection.Add(codeNamespace);
- if (CanDeclareAssemblyAttribute(contractCodeDomInfo)
- && NeedsExplicitNamespace(dataContractNamespace, clrNamespace))
- {
- CodeAttributeDeclaration namespaceAttribute = new CodeAttributeDeclaration(DataContract.GetClrTypeFullName(Globals.TypeOfContractNamespaceAttribute));
- namespaceAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(dataContractNamespace)));
- namespaceAttribute.Arguments.Add(new CodeAttributeArgument(Globals.ClrNamespaceProperty, new CodePrimitiveExpression(clrNamespace)));
- codeCompileUnit.AssemblyCustomAttributes.Add(namespaceAttribute);
- }
- contractCodeDomInfo.CodeNamespace = codeNamespace;
- return codeNamespace;
- }
- string GetMemberName(string memberName, ContractCodeDomInfo contractCodeDomInfo)
- {
- memberName = GetClrIdentifier(memberName, Globals.DefaultGeneratedMember);
- if (memberName == contractCodeDomInfo.TypeDeclaration.Name)
- memberName = AppendToValidClrIdentifier(memberName, Globals.DefaultMemberSuffix);
- if (contractCodeDomInfo.GetMemberNames().ContainsKey(memberName))
- {
- string uniqueMemberName = null;
- for (int i = 1;; i++)
- {
- uniqueMemberName = AppendToValidClrIdentifier(memberName, i.ToString(NumberFormatInfo.InvariantInfo));
- if (!contractCodeDomInfo.GetMemberNames().ContainsKey(uniqueMemberName))
- {
- memberName = uniqueMemberName;
- break;
- }
- }
- }
- contractCodeDomInfo.GetMemberNames().Add(memberName, null);
- return memberName;
- }
- void AddBaseMemberNames(ContractCodeDomInfo baseContractCodeDomInfo, ContractCodeDomInfo contractCodeDomInfo)
- {
- if (!baseContractCodeDomInfo.ReferencedTypeExists)
- {
- Dictionary<string, object> baseMemberNames = baseContractCodeDomInfo.GetMemberNames();
- Dictionary<string, object> memberNames = contractCodeDomInfo.GetMemberNames();
- foreach (KeyValuePair<string, object> pair in baseMemberNames)
- {
- memberNames.Add(pair.Key, pair.Value);
- }
- }
- }
- [Fx.Tag.SecurityNote(Critical = "Critical because it calls the CodeGenerator.IsValidLanguageIndependentIdentifier(..) method that has a LinkDemand.",
- Safe = "Safe because it doesn't leak security sensitive information.")]
- [SecuritySafeCritical]
- static string GetClrIdentifier(string identifier, string defaultIdentifier)
- {
- if (identifier.Length <= MaxIdentifierLength && System.CodeDom.Compiler.CodeGenerator.IsValidLanguageIndependentIdentifier(identifier))
- return identifier;
- bool isStart = true;
- StringBuilder builder = new StringBuilder();
- for (int i = 0; i < identifier.Length && builder.Length < MaxIdentifierLength; i++)
- {
- char c = identifier[i];
- if (IsValid(c))
- {
- if (isStart && !IsValidStart(c))
- builder.Append("_");
- builder.Append(c);
- isStart = false;
- }
- }
- if (builder.Length == 0)
- return defaultIdentifier;
- return builder.ToString();
- }
- static string AppendToValidClrIdentifier(string identifier, string appendString)
- {
- int availableLength = MaxIdentifierLength - identifier.Length;
- int requiredLength = appendString.Length;
- if (availableLength < requiredLength)
- identifier = identifier.Substring(0, MaxIdentifierLength - requiredLength);
- identifier += appendString;
- return identifier;
- }
- string GetClrNamespace(DataContract dataContract, ContractCodeDomInfo contractCodeDomInfo)
- {
- string clrNamespace = contractCodeDomInfo.ClrNamespace;
- bool usesWildcardNamespace = false;
- if (clrNamespace == null)
- {
- if (!Namespaces.TryGetValue(dataContract.StableName.Namespace, out clrNamespace))
- {
- if (Namespaces.TryGetValue(wildcardNamespaceMapping, out clrNamespace))
- {
- usesWildcardNamespace = true;
- }
- else
- {
- clrNamespace = GetClrNamespace(dataContract.StableName.Namespace);
- if (ClrNamespaces.ContainsKey(clrNamespace))
- {
- string uniqueNamespace = null;
- for (int i = 1;; i++)
- {
- uniqueNamespace = ((clrNamespace.Length == 0) ? Globals.DefaultClrNamespace : clrNamespace) + i.ToString(NumberFormatInfo.InvariantInfo);
- if (!ClrNamespaces.ContainsKey(uniqueNamespace))
- {
- clrNamespace = uniqueNamespace;
- break;
- }
- }
- }
- AddNamespacePair(dataContract.StableName.Namespace, clrNamespace);
- }
- }
- contractCodeDomInfo.ClrNamespace = clrNamespace;
- contractCodeDomInfo.UsesWildcardNamespace = usesWildcardNamespace;
- }
- return clrNamespace;
- }
- void AddNamespacePair(string dataContractNamespace, string clrNamespace)
- {
- Namespaces.Add(dataContractNamespace, clrNamespace);
- ClrNamespaces.Add(clrNamespace, dataContractNamespace);
- }
- void AddImportStatement(string clrNamespace, CodeNamespace codeNamespace)
- {
- if (clrNamespace == codeNamespace.Name)
- return;
- CodeNamespaceImportCollection importCollection = codeNamespace.Imports;
- foreach (CodeNamespaceImport import in importCollection)
- {
- if (import.Namespace == clrNamespace)
- return;
- }
- importCollection.Add(new CodeNamespaceImport(clrNamespace));
- }
- static string GetClrNamespace(string dataContractNamespace)
- {
- if (dataContractNamespace == null || dataContractNamespace.Length == 0)
- return String.Empty;
- Uri uri = null;
- StringBuilder builder = new StringBuilder();
- if (Uri.TryCreate(dataContractNamespace, UriKind.RelativeOrAbsolute, out uri))
- {
- Dictionary<string, object> fragments = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
- if (!uri.IsAbsoluteUri)
- AddToNamespace(builder, uri.OriginalString, fragments);
- else
- {
- string uriString = uri.AbsoluteUri;
- if (uriString.StartsWith(Globals.DataContractXsdBaseNamespace, StringComparison.Ordinal))
- AddToNamespace(builder, uriString.Substring(Globals.DataContractXsdBaseNamespace.Length), fragments);
- else
- {
- string host = uri.Host;
- if (host != null)
- AddToNamespace(builder, host, fragments);
- string path = uri.PathAndQuery;
- if (path != null)
- AddToNamespace(builder, path, fragments);
- }
- }
- }
- if (builder.Length == 0)
- return String.Empty;
- int length = builder.Length;
- if (builder[builder.Length - 1] == '.')
- length--;
- length = Math.Min(MaxIdentifierLength, length);
- return builder.ToString(0, length);
- }
- static void AddToNamespace(StringBuilder builder, string fragment, Dictionary<string, object> fragments)
- {
- if (fragment == null)
- return;
- bool isStart = true;
- int fragmentOffset = builder.Length;
- int fragmentLength = 0;
- for (int i = 0; i < fragment.Length && builder.Length < MaxIdentifierLength; i++)
- {
- char c = fragment[i];
- if (IsValid(c))
- {
- if (isStart && !IsValidStart(c))
- builder.Append("_");
- builder.Append(c);
- fragmentLength++;
- isStart = false;
- }
- else if ((c == '.' || c == '/' || c == ':') && (builder.Length == 1
- || (builder.Length > 1 && builder[builder.Length - 1] != '.')))
- {
- AddNamespaceFragment(builder, fragmentOffset, fragmentLength, fragments);
- builder.Append('.');
- fragmentOffset = builder.Length;
- fragmentLength = 0;
- isStart = true;
- }
- }
- AddNamespaceFragment(builder, fragmentOffset, fragmentLength, fragments);
- }
- static void AddNamespaceFragment(StringBuilder builder, int fragmentOffset,
- int fragmentLength, Dictionary<string, object> fragments)
- {
- if (fragmentLength == 0)
- return;
- string nsFragment = builder.ToString(fragmentOffset, fragmentLength);
- if (fragments.ContainsKey(nsFragment))
- {
- for (int i = 1;; i++)
- {
- string uniquifier = i.ToString(NumberFormatInfo.InvariantInfo);
- string uniqueNsFragment = AppendToValidClrIdentifier(nsFragment, uniquifier);
- if (!fragments.ContainsKey(uniqueNsFragment))
- {
- builder.Append(uniquifier);
- nsFragment = uniqueNsFragment;
- break;
- }
- if (i == Int32.MaxValue)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidDataContractException(SR.GetString(SR.CannotComputeUniqueName, nsFragment)));
- }
- }
- fragments.Add(nsFragment, null);
- }
- static bool IsValidStart(char c)
- {
- return (Char.GetUnicodeCategory(c) != UnicodeCategory.DecimalDigitNumber);
- }
- static bool IsValid(char c)
- {
- UnicodeCategory uc = Char.GetUnicodeCategory(c);
- // each char must be Lu, Ll, Lt, Lm, Lo, Nd, Mn, Mc, Pc
- switch (uc)
- {
- case UnicodeCategory.UppercaseLetter: // Lu
- case UnicodeCategory.LowercaseLetter: // Ll
- case UnicodeCategory.TitlecaseLetter: // Lt
- case UnicodeCategory.ModifierLetter: // Lm
- case UnicodeCategory.OtherLetter: // Lo
- case UnicodeCategory.DecimalDigitNumber: // Nd
- case UnicodeCategory.NonSpacingMark: // Mn
- case UnicodeCategory.SpacingCombiningMark: // Mc
- case UnicodeCategory.ConnectorPunctuation: // Pc
- return true;
- default:
- return false;
- }
- }
- CodeTypeReference CodeTypeIPropertyChange
- {
- get { return GetCodeTypeReference(typeof(System.ComponentModel.INotifyPropertyChanged)); }
- }
- CodeThisReferenceExpression ThisReference
- {
- get { return new CodeThisReferenceExpression(); }
- }
- CodePrimitiveExpression NullReference
- {
- get { return new CodePrimitiveExpression(null); }
- }
- CodeParameterDeclarationExpression SerializationInfoParameter
- {
- get { return new CodeParameterDeclarationExpression(GetCodeTypeReference(Globals.TypeOfSerializationInfo), Globals.SerializationInfoFieldName); }
- }
- CodeParameterDeclarationExpression StreamingContextParameter
- {
- get { return new CodeParameterDeclarationExpression(GetCodeTypeReference(Globals.TypeOfStreamingContext), Globals.ContextFieldName); }
- }
- CodeAttributeDeclaration SerializableAttribute
- {
- get { return new CodeAttributeDeclaration(GetCodeTypeReference(Globals.TypeOfSerializableAttribute)); }
- }
- CodeMemberProperty NodeArrayProperty
- {
- get
- {
- return CreateProperty(GetCodeTypeReference(Globals.TypeOfXmlNodeArray), Globals.NodeArrayPropertyName, Globals.NodeArrayFieldName, false/*isValueType*/);
- }
- }
- CodeMemberField NodeArrayField
- {
- get
- {
- CodeMemberField nodeArrayField = new CodeMemberField();
- nodeArrayField.Type = GetCodeTypeReference(Globals.TypeOfXmlNodeArray);
- nodeArrayField.Name = Globals.NodeArrayFieldName;
- nodeArrayField.Attributes = MemberAttributes.Private;
- return nodeArrayField;
- }
- }
- CodeMemberMethod ReadXmlMethod
- {
- get
- {
- CodeMemberMethod readXmlMethod = new CodeMemberMethod();
- readXmlMethod.Name = "ReadXml";
- CodeParameterDeclarationExpression readerArg = new CodeParameterDeclarationExpression(typeof(XmlReader), "reader");
- readXmlMethod.Parameters.Add(readerArg);
- readXmlMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- readXmlMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable);
- CodeAssignStatement setNode = new CodeAssignStatement();
- setNode.Left = new CodeFieldReferenceExpression(ThisReference, Globals.NodeArrayFieldName);
- setNode.Right = new CodeMethodInvokeExpression(
- new CodeTypeReferenceExpression(GetCodeTypeReference(Globals.TypeOfXmlSerializableServices)),
- XmlSerializableServices.ReadNodesMethodName,
- new CodeArgumentReferenceExpression(readerArg.Name)
- );
- readXmlMethod.Statements.Add(setNode);
- return readXmlMethod;
- }
- }
- CodeMemberMethod WriteXmlMethod
- {
- get
- {
- CodeMemberMethod writeXmlMethod = new CodeMemberMethod();
- writeXmlMethod.Name = "WriteXml";
- CodeParameterDeclarationExpression writerArg = new CodeParameterDeclarationExpression(typeof(XmlWriter), "writer");
- writeXmlMethod.Parameters.Add(writerArg);
- writeXmlMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- writeXmlMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable);
- writeXmlMethod.Statements.Add(
- new CodeMethodInvokeExpression(
- new CodeTypeReferenceExpression(GetCodeTypeReference(Globals.TypeOfXmlSerializableServices)),
- XmlSerializableServices.WriteNodesMethodName,
- new CodeArgumentReferenceExpression(writerArg.Name),
- new CodePropertyReferenceExpression(ThisReference, Globals.NodeArrayPropertyName)
- )
- );
- return writeXmlMethod;
- }
- }
- CodeMemberMethod GetSchemaMethod
- {
- get
- {
- CodeMemberMethod getSchemaMethod = new CodeMemberMethod();
- getSchemaMethod.Name = "GetSchema";
- getSchemaMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- getSchemaMethod.ImplementationTypes.Add(Globals.TypeOfIXmlSerializable);
- getSchemaMethod.ReturnType = GetCodeTypeReference(typeof(XmlSchema));
- getSchemaMethod.Statements.Add(new CodeMethodReturnStatement(NullReference));
- return getSchemaMethod;
- }
- }
- CodeMemberMethod GetSchemaStaticMethod
- {
- get
- {
- CodeMemberMethod getSchemaStaticMethod = new CodeMemberMethod();
- getSchemaStaticMethod.Name = Globals.ExportSchemaMethod;
- getSchemaStaticMethod.ReturnType = GetCodeTypeReference(Globals.TypeOfXmlQualifiedName);
- CodeParameterDeclarationExpression paramDeclaration = new CodeParameterDeclarationExpression(Globals.TypeOfXmlSchemaSet, "schemas");
- getSchemaStaticMethod.Parameters.Add(paramDeclaration);
- getSchemaStaticMethod.Attributes = MemberAttributes.Static | MemberAttributes.Public;
- getSchemaStaticMethod.Statements.Add(
- new CodeMethodInvokeExpression(
- new CodeTypeReferenceExpression(GetCodeTypeReference(typeof(XmlSerializableServices))),
- XmlSerializableServices.AddDefaultSchemaMethodName,
- new CodeArgumentReferenceExpression(paramDeclaration.Name),
- new CodeFieldReferenceExpression(null, typeNameFieldName)
- )
- );
- getSchemaStaticMethod.Statements.Add(
- new CodeMethodReturnStatement(
- new CodeFieldReferenceExpression(null, typeNameFieldName)
- )
- );
- return getSchemaStaticMethod;
- }
- }
- CodeConstructor ISerializableBaseConstructor
- {
- get
- {
- CodeConstructor baseConstructor = new CodeConstructor();
- baseConstructor.Attributes = MemberAttributes.Public;
- baseConstructor.Parameters.Add(SerializationInfoParameter);
- baseConstructor.Parameters.Add(StreamingContextParameter);
- CodeAssignStatement setObjectData = new CodeAssignStatement();
- setObjectData.Left = new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoFieldName);
- setObjectData.Right = new CodeArgumentReferenceExpression(Globals.SerializationInfoFieldName);
- baseConstructor.Statements.Add(setObjectData);
- // Special-cased check for vb here since CodeGeneratorOptions does not provide information indicating that VB cannot initialize event member
- if (EnableDataBinding && SupportsDeclareEvents && String.CompareOrdinal(FileExtension, "vb") != 0)
- {
- baseConstructor.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(ThisReference, PropertyChangedEvent.Name), NullReference));
- }
- return baseConstructor;
- }
- }
- CodeConstructor ISerializableDerivedConstructor
- {
- get
- {
- CodeConstructor derivedConstructor = new CodeConstructor();
- derivedConstructor.Attributes = MemberAttributes.Public;
- derivedConstructor.Parameters.Add(SerializationInfoParameter);
- derivedConstructor.Parameters.Add(StreamingContextParameter);
- derivedConstructor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(Globals.SerializationInfoFieldName));
- derivedConstructor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(Globals.ContextFieldName));
- return derivedConstructor;
- }
- }
- CodeMemberField SerializationInfoField
- {
- get
- {
- CodeMemberField serializationInfoField = new CodeMemberField();
- serializationInfoField.Type = GetCodeTypeReference(Globals.TypeOfSerializationInfo);
- serializationInfoField.Name = Globals.SerializationInfoFieldName;
- serializationInfoField.Attributes = MemberAttributes.Private;
- return serializationInfoField;
- }
- }
- CodeMemberProperty SerializationInfoProperty
- {
- get
- {
- return CreateProperty(GetCodeTypeReference(Globals.TypeOfSerializationInfo), Globals.SerializationInfoPropertyName, Globals.SerializationInfoFieldName, false/*isValueType*/);
- }
- }
- CodeMemberMethod GetObjectDataMethod
- {
- get
- {
- CodeMemberMethod getObjectDataMethod = new CodeMemberMethod();
- getObjectDataMethod.Name = Globals.GetObjectDataMethodName;
- getObjectDataMethod.Parameters.Add(SerializationInfoParameter);
- getObjectDataMethod.Parameters.Add(StreamingContextParameter);
- getObjectDataMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- getObjectDataMethod.ImplementationTypes.Add(Globals.TypeOfISerializable);
- // Generates: if (this.SerializationInfo == null) return;
- CodeConditionStatement returnIfNull = new CodeConditionStatement();
- returnIfNull.Condition = new CodeBinaryOperatorExpression(
- new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoPropertyName),
- CodeBinaryOperatorType.IdentityEquality,
- NullReference);
- returnIfNull.TrueStatements.Add(new CodeMethodReturnStatement());
- // Generates: SerializationInfoEnumerator enumerator = this.SerializationInfo.GetEnumerator();
- CodeVariableDeclarationStatement getEnumerator = new CodeVariableDeclarationStatement();
- getEnumerator.Type = GetCodeTypeReference(Globals.TypeOfSerializationInfoEnumerator);
- getEnumerator.Name = Globals.EnumeratorFieldName;
- getEnumerator.InitExpression = new CodeMethodInvokeExpression(
- new CodePropertyReferenceExpression(ThisReference, Globals.SerializationInfoPropertyName),
- Globals.GetEnumeratorMethodName);
- //Generates: SerializationEntry entry = enumerator.Current;
- CodeVariableDeclarationStatement getCurrent = new CodeVariableDeclarationStatement();
- getCurrent.Type = GetCodeTypeReference(Globals.TypeOfSerializationEntry);
- getCurrent.Name = Globals.SerializationEntryFieldName;
- getCurrent.InitExpression = new CodePropertyReferenceExpression(
- new CodeVariableReferenceExpression(Globals.EnumeratorFieldName),
- Globals.CurrentPropertyName);
- //Generates: info.AddValue(entry.Name, entry.Value);
- CodeExpressionStatement addValue = new CodeExpressionStatement();
- CodePropertyReferenceExpression getCurrentName = new CodePropertyReferenceExpression(
- new CodeVariableReferenceExpression(Globals.SerializationEntryFieldName),
- Globals.NameProperty);
- CodePropertyReferenceExpression getCurrentValue = new CodePropertyReferenceExpression(
- new CodeVariableReferenceExpression(Globals.SerializationEntryFieldName),
- Globals.ValueProperty);
- addValue.Expression = new CodeMethodInvokeExpression(
- new CodeArgumentReferenceExpression(Globals.SerializationInfoFieldName),
- Globals.AddValueMethodName,
- new CodeExpression[] { getCurrentName, getCurrentValue });
- //Generates: for (; enumerator.MoveNext(); )
- CodeIterationStatement loop = new CodeIterationStatement();
- loop.TestExpression = new CodeMethodInvokeExpression(
- new CodeVariableReferenceExpression(Globals.EnumeratorFieldName),
- Globals.MoveNextMethodName);
- loop.InitStatement = loop.IncrementStatement = new CodeSnippetStatement(String.Empty);
- loop.Statements.Add(getCurrent);
- loop.Statements.Add(addValue);
- getObjectDataMethod.Statements.Add(returnIfNull);
- getObjectDataMethod.Statements.Add(getEnumerator);
- getObjectDataMethod.Statements.Add(loop);
- return getObjectDataMethod;
- }
- }
- CodeMemberField ExtensionDataObjectField
- {
- get
- {
- CodeMemberField extensionDataObjectField = new CodeMemberField();
- extensionDataObjectField.Type = GetCodeTypeReference(Globals.TypeOfExtensionDataObject);
- extensionDataObjectField.Name = Globals.ExtensionDataObjectFieldName;
- extensionDataObjectField.Attributes = MemberAttributes.Private;
- return extensionDataObjectField;
- }
- }
- CodeMemberProperty ExtensionDataObjectProperty
- {
- get
- {
- CodeMemberProperty extensionDataObjectProperty = new CodeMemberProperty();
- extensionDataObjectProperty.Type = GetCodeTypeReference(Globals.TypeOfExtensionDataObject);
- extensionDataObjectProperty.Name = Globals.ExtensionDataObjectPropertyName;
- extensionDataObjectProperty.Attributes = MemberAttributes.Public | MemberAttributes.Final;
- extensionDataObjectProperty.ImplementationTypes.Add(Globals.TypeOfIExtensibleDataObject);
- CodeMethodReturnStatement propertyGet = new CodeMethodReturnStatement();
- propertyGet.Expression = new CodeFieldReferenceExpression(ThisReference, Globals.ExtensionDataObjectFieldName);
- extensionDataObjectProperty.GetStatements.Add(propertyGet);
- CodeAssignStatement propertySet = new CodeAssignStatement();
- propertySet.Left = new CodeFieldReferenceExpression(ThisReference, Globals.ExtensionDataObjectFieldName);
- propertySet.Right = new CodePropertySetValueReferenceExpression();
- extensionDataObjectProperty.SetStatements.Add(propertySet);
- return extensionDataObjectProperty;
- }
- }
- CodeMemberMethod RaisePropertyChangedEventMethod
- {
- get
- {
- CodeMemberMethod raisePropertyChangedEventMethod = new CodeMemberMethod();
- raisePropertyChangedEventMethod.Name = "RaisePropertyChanged";
- raisePropertyChangedEventMethod.Attributes = MemberAttributes.Final;
- CodeArgumentReferenceExpression propertyName = new CodeArgumentReferenceExpression("propertyName");
- raisePropertyChangedEventMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), propertyName.ParameterName));
- CodeVariableReferenceExpression propertyChanged = new CodeVariableReferenceExpression("propertyChanged");
- raisePropertyChangedEventMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(PropertyChangedEventHandler), propertyChanged.VariableName, new CodeEventReferenceExpression(ThisReference, PropertyChangedEvent.Name)));
- CodeConditionStatement ifStatement = new CodeConditionStatement(new CodeBinaryOperatorExpression(propertyChanged, CodeBinaryOperatorType.IdentityInequality, NullReference));
- raisePropertyChangedEventMethod.Statements.Add(ifStatement);
- ifStatement.TrueStatements.Add(new CodeDelegateInvokeExpression(propertyChanged, ThisReference, new CodeObjectCreateExpression(typeof(PropertyChangedEventArgs), propertyName)));
- return raisePropertyChangedEventMethod;
- }
- }
- CodeMemberEvent PropertyChangedEvent
- {
- get
- {
- CodeMemberEvent propertyChangedEvent = new CodeMemberEvent();
- propertyChangedEvent.Attributes = MemberAttributes.Public;
- propertyChangedEvent.Name = "PropertyChanged";
- propertyChangedEvent.Type = GetCodeTypeReference(typeof(PropertyChangedEventHandler));
- propertyChangedEvent.ImplementationTypes.Add(Globals.TypeOfIPropertyChange);
- return propertyChangedEvent;
- }
- }
- CodeMemberProperty CreateProperty(CodeTypeReference type, string propertyName, string fieldName, bool isValueType)
- {
- return CreateProperty(type, propertyName, fieldName, isValueType, EnableDataBinding && SupportsDeclareEvents);
- }
- CodeMemberProperty CreateProperty(CodeTypeReference type, string propertyName, string fieldName, bool isValueType, bool raisePropertyChanged)
- {
- CodeMemberProperty property = new CodeMemberProperty();
- property.Type = type;
- property.Name = propertyName;
- property.Attributes = MemberAttributes.Final;
- if (GenerateInternalTypes)
- property.Attributes |= MemberAttributes.Assembly;
- else
- property.Attributes |= MemberAttributes.Public;
- CodeMethodReturnStatement propertyGet = new CodeMethodReturnStatement();
- propertyGet.Expression = new CodeFieldReferenceExpression(ThisReference, fieldName);
- property.GetStatements.Add(propertyGet);
- CodeAssignStatement propertySet = new CodeAssignStatement();
- propertySet.Left = new CodeFieldReferenceExpression(ThisReference, fieldName);
- propertySet.Right = new CodePropertySetValueReferenceExpression();
- if (raisePropertyChanged)
- {
- CodeConditionStatement ifStatement = new CodeConditionStatement();
- CodeExpression left = new CodeFieldReferenceExpression(ThisReference, fieldName);
- CodeExpression right = new CodePropertySetValueReferenceExpression();
- if (!isValueType)
- {
- left = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression(Globals.TypeOfObject),
- "ReferenceEquals", new CodeExpression[] { left, right });
- }
- else
- {
- left = new CodeMethodInvokeExpression(left, "Equals", new CodeExpression[] { right });
- }
- right = new CodePrimitiveExpression(true);
- ifStatement.Condition = new CodeBinaryOperatorExpression(left, CodeBinaryOperatorType.IdentityInequality, right);
- ifStatement.TrueStatements.Add(propertySet);
- ifStatement.TrueStatements.Add(new CodeMethodInvokeExpression(ThisReference, RaisePropertyChangedEventMethod.Name, new CodePrimitiveExpression(propertyName)));
- property.SetStatements.Add(ifStatement);
- }
- else
- property.SetStatements.Add(propertySet);
- return property;
- }
- }
- }
|