Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ internal CodeTypeReference GetCodeTypeReference(DataContract dataContract)

// This is supposed to be set by GenerateType. If it wasn't, there is a problem.
Debug.Assert(contractCodeDomInfo.TypeReference != null);
return contractCodeDomInfo.TypeReference!;
return contractCodeDomInfo.TypeReference;
}

private CodeTypeReference GetCodeTypeReference(Type type)
Expand Down Expand Up @@ -493,7 +493,8 @@ private void GenerateType(DataContract dataContract, ContractCodeDomInfo contrac
if (containingContractCodeDomInfo.ReferencedTypeExists)
return null;

CodeTypeDeclaration containingType = containingContractCodeDomInfo.TypeDeclaration!; // Nested types by definition have containing types.
Debug.Assert(containingContractCodeDomInfo.TypeDeclaration != null, "Nested types have containing types by definition - types with declaration");
CodeTypeDeclaration containingType = containingContractCodeDomInfo.TypeDeclaration;
if (TypeContainsNestedType(containingType, nestedTypeName))
{
for (int i = 1; ; i++)
Expand All @@ -509,7 +510,8 @@ private void GenerateType(DataContract dataContract, ContractCodeDomInfo contrac

CodeTypeDeclaration type = CreateTypeDeclaration(nestedTypeName, dataContract);
containingType.Members.Add(type);
contractCodeDomInfo.TypeReference = new CodeTypeReference(containingContractCodeDomInfo.TypeReference!.BaseType + "+" + nestedTypeName); // Again, nested types by definition have containing types.
Debug.Assert(containingContractCodeDomInfo.TypeReference != null, "Nested types have containing types by definition - types with reference");
contractCodeDomInfo.TypeReference = new CodeTypeReference(containingContractCodeDomInfo.TypeReference.BaseType + "+" + nestedTypeName);

if (GenerateInternalTypes)
type.TypeAttributes = TypeAttributes.NestedAssembly;
Expand All @@ -525,8 +527,9 @@ private static CodeTypeDeclaration CreateTypeDeclaration(string typeName, DataCo
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()!)));
Debug.Assert(assemblyName.Name != null, $"Current executing assembly name is not expected to be null in {nameof(CodeExporter)}.{nameof(CreateTypeDeclaration)} scenario");
generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Name)));
generatedCodeAttribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Version?.ToString())));
Comment thread
StephenMolloy marked this conversation as resolved.

// System.Diagnostics.DebuggerStepThroughAttribute not allowed on enums
// ensure that the attribute is only generated on types that are not enums
Expand Down Expand Up @@ -614,7 +617,8 @@ private static CodeTypeDeclaration CreateTypeDeclaration(string typeName, DataCo
if (!TryGetReferencedDictionaryType(collectionContract, out typeReference))
{
// ItemContract - aka BaseContract - is never null for CollectionDataContract
DataContract itemContract = collectionContract.BaseContract!;
Debug.Assert(collectionContract.BaseContract != null, "BaseContract should not be null for CollectionDataContract");
Comment thread
StephenMolloy marked this conversation as resolved.
DataContract itemContract = collectionContract.BaseContract;
if (collectionContract.IsDictionaryLike(out _, out _, out _))
{
GenerateKeyValueType(itemContract.As(DataContractType.ClassDataContract));
Expand All @@ -635,10 +639,11 @@ private static CodeTypeDeclaration CreateTypeDeclaration(string typeName, DataCo
[RequiresUnreferencedCode(ImportGlobals.SerializerTrimmerWarning)]
private bool HasDefaultCollectionNames(DataContract collectionContract)
{
// ItemContract - aka BaseContract - is never null for CollectionDataContract
Debug.Assert(collectionContract.Is(DataContractType.CollectionDataContract));
Debug.Assert(collectionContract.BaseContract != null, "BaseContract should not be null for CollectionDataContract");

// ItemContract - aka BaseContract - is never null for CollectionDataContract
DataContract itemContract = collectionContract.BaseContract!;
DataContract itemContract = collectionContract.BaseContract;
bool isDictionary = collectionContract.IsDictionaryLike(out string? keyName, out string? valueName, out string? itemName);
if (itemName != itemContract.XmlName.Name)
return false;
Expand All @@ -654,6 +659,7 @@ private bool HasDefaultCollectionNames(DataContract collectionContract)
private bool TryGetReferencedDictionaryType(DataContract collectionContract, [NotNullWhen(true)] out CodeTypeReference? typeReference)
{
Debug.Assert(collectionContract.Is(DataContractType.CollectionDataContract));
Debug.Assert(collectionContract.BaseContract != null, "BaseContract should not be null for CollectionDataContract");

// Check if it is a dictionary and use referenced dictionary type if present
if (collectionContract.IsDictionaryLike(out _, out _, out _)
Expand All @@ -662,7 +668,7 @@ private bool TryGetReferencedDictionaryType(DataContract collectionContract, [No
Type? type = _dataContractSet.GetReferencedType(GenericDictionaryName, GenericDictionaryContract, out DataContract? _, out object[]? _) ?? typeof(Dictionary<,>);

// ItemContract - aka BaseContract - is never null for CollectionDataContract
DataContract? itemContract = collectionContract.BaseContract!.As(DataContractType.ClassDataContract);
DataContract? itemContract = collectionContract.BaseContract.As(DataContractType.ClassDataContract);

// A dictionary should have a Key/Value item contract that has at least two members: key and value.
Debug.Assert(itemContract != null);
Expand Down Expand Up @@ -693,7 +699,7 @@ private bool TryGetReferencedListType(DataContract itemContract, bool isItemType
if (type != null)
{
typeReference = GetCodeTypeReference(type);
typeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable)!); // Lists have an item type
typeReference.TypeArguments.Add(GetElementTypeReference(itemContract, isItemTypeNullable)); // Lists have an item type
return true;
}
}
Expand Down Expand Up @@ -826,7 +832,8 @@ private void ExportClassDataContract(DataContract classDataContract, ContractCod
{
ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(classDataContract.BaseContract);
Debug.Assert(baseContractCodeDomInfo.IsProcessed, "Cannot generate code for type if code for base type has not been generated");
type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference!);
Debug.Assert(baseContractCodeDomInfo.TypeReference != null, "Class data contracts should have non-null TypeReference");
type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference);
AddBaseMemberNames(baseContractCodeDomInfo, contractCodeDomInfo);
if (baseContractCodeDomInfo.ReferencedTypeExists)
{
Expand Down Expand Up @@ -1075,7 +1082,8 @@ private void ExportEnumDataContract(DataContract enumDataContract, ContractCodeD

CodeTypeDeclaration type = contractCodeDomInfo.TypeDeclaration;
// BaseContract is never null for EnumDataContract
Type baseType = enumDataContract.BaseContract!.UnderlyingType;
Debug.Assert(enumDataContract.BaseContract != null, "BaseContract should not be null for EnumDataContract");
Type baseType = enumDataContract.BaseContract.UnderlyingType;
type.IsEnum = true;
type.BaseTypes.Add(baseType);
if (baseType.IsDefined(typeof(FlagsAttribute), false))
Expand Down Expand Up @@ -1159,7 +1167,9 @@ private void ExportISerializableDataContract(DataContract classDataContract, Con
{
ContractCodeDomInfo baseContractCodeDomInfo = GetContractCodeDomInfo(classDataContract.BaseContract);
GenerateType(classDataContract.BaseContract, baseContractCodeDomInfo);
type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference!);

Debug.Assert(baseContractCodeDomInfo.TypeReference != null, "Class data contracts should have non-null TypeReference");
type.BaseTypes.Add(baseContractCodeDomInfo.TypeReference);
if (baseContractCodeDomInfo.ReferencedTypeExists)
{
Type? actualType = (Type?)baseContractCodeDomInfo.TypeReference?.UserData[s_codeUserDataActualTypeKey];
Expand Down Expand Up @@ -1210,6 +1220,7 @@ private void ExportCollectionDataContract(DataContract collectionContract, Contr
collectionContract.XmlName.Namespace)));

// ItemContract - aka BaseContract - is never null for CollectionDataContract
Debug.Assert(collectionContract.BaseContract != null, "BaseContract should not be null for CollectionDataContract");
DataContract itemContract = collectionContract.BaseContract!;
bool isItemTypeNullable = GetCollectionItemNullability(collectionContract);
bool isDictionary = collectionContract.IsDictionaryLike(out string? keyName, out string? valueName, out string? itemName);
Expand Down Expand Up @@ -1242,15 +1253,17 @@ private void ExportCollectionDataContract(DataContract collectionContract, Contr

// This is supposed to be set by GenerateType. If it wasn't, there is a problem.
Debug.Assert(contractCodeDomInfo.TypeDeclaration != null);
Debug.Assert(baseTypeReference != null, "Base type reference should not be null for Dictionary/List collection data contracts");

CodeTypeDeclaration generatedType = contractCodeDomInfo.TypeDeclaration;
generatedType.BaseTypes.Add(baseTypeReference!);
generatedType.BaseTypes.Add(baseTypeReference);
CodeAttributeDeclaration collectionContractAttribute = new CodeAttributeDeclaration(GetClrTypeFullName(typeof(CollectionDataContractAttribute)));
collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(ImportGlobals.NameProperty, new CodePrimitiveExpression(dataContractName)));
collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(ImportGlobals.NamespaceProperty, new CodePrimitiveExpression(collectionContract.XmlName.Namespace)));
if (collectionContract.IsReference != ImportGlobals.DefaultIsReference)
collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(ImportGlobals.IsReferenceProperty, new CodePrimitiveExpression(collectionContract.IsReference)));
collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(ImportGlobals.ItemNameProperty, new CodePrimitiveExpression(GetNameForAttribute(itemName!)))); // ItemName is never null for Collection contracts.
Debug.Assert(itemName != null, "ItemName is never null for Collection contracts.");
collectionContractAttribute.Arguments.Add(new CodeAttributeArgument(ImportGlobals.ItemNameProperty, new CodePrimitiveExpression(GetNameForAttribute(itemName))));
if (foundDictionaryBase)
{
// These are not null if we are working with a dictionary. See CollectionDataContract.IsDictionary
Expand Down Expand Up @@ -1440,7 +1453,9 @@ private static string GetClrIdentifier(string identifier, string defaultIdentifi

internal static string GetClrTypeFullName(Type type)
{
return !type.IsGenericTypeDefinition && type.ContainsGenericParameters ? type.Namespace + "." + type.Name : type.FullName!;
// Type.FullName can be null for types that contain unassigned generic parameters and for generic type parameters,
// so construct a fallback name only when FullName is unavailable.
return type.FullName ?? (type.Namespace == null ? type.Name : type.Namespace + "." + type.Name);
}

private static string AppendToValidClrIdentifier(string identifier, string appendString)
Expand Down
Loading