Skip to content
Closed
Show file tree
Hide file tree
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
224 changes: 51 additions & 173 deletions .editorconfig

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion GeneratedSchemaLibraries/buildAll.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ $buildResults = New-Object System.Collections.Generic.List[BuildResult];
$dnb = Get-Command dotnet

Get-ChildItem -Attributes Directory | % {
if ($_ -contains "Microsoft Project 2007") { return; }
if ($_.Name -contains "Microsoft Project 2007") { return; }
$projects = [System.IO.Directory]::GetFiles($_.FullName, "*.csproj");
$first = $projects[0];

Expand Down
47 changes: 34 additions & 13 deletions XObjectsCode/Src/ClrPropertyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -349,29 +349,40 @@ public void UpdateTypeReference(
string currentTypeScope,
string currentNamespaceScope,
Dictionary<XmlSchemaObject, string> nameMappings,
Action<ClrTypeReference> createNestedEnumType)
Action<ClrTypeReference, ClrTypeReference>? createNestedEnumType)
{
var typeRef = this.TypeReference;
var nestedEnumClassWasCreated = false;
if (typeRef.IsEnum)
{
if (string.IsNullOrEmpty(typeRef.Name))
{
typeRef.Name = $"{this.PropertyName.ToUpperFirstInvariant()}{Constants.LocalEnumSuffix}";
}
if (ShouldGenerate && typeRef.IsLocalType && createNestedEnumType != null)
if (ShouldGenerate && (typeRef.IsLocalType || this.typeRef.IsForAnonymousXsdType) && createNestedEnumType != null)
{
createNestedEnumType(typeRef);
createNestedEnumType(typeRef, this.TypeReference);
nestedEnumClassWasCreated = true;
}
}

this.clrTypeName = typeRef.GetClrFullTypeName(currentNamespaceScope, nameMappings, settings, out string refTypeName);

if ((Validation || IsUnion) || IsEnum)
{
this.simpleTypeClrTypeName = typeRef.GetSimpleTypeClrTypeDefName(currentNamespaceScope, nameMappings);
// when a nested enum class is made, then the simpleTypeClrTypeName be the fullBy qualified name of the nested enum class (inc namespace);
// otherwise it will be the namespace
if (nestedEnumClassWasCreated) {
Debug.Assert(currentTypeScope.StartsWith(currentNamespaceScope),
"currentTypeScope should also start with the currentNamespaceScope!");
this.simpleTypeClrTypeName += $"{typeRef.Name}";
}
else {
this.simpleTypeClrTypeName = typeRef.GetSimpleTypeClrTypeDefName(currentNamespaceScope, nameMappings);
}
}

this.parentTypeFullName = typeRef.IsEnum ? typeRef.UpdateClrFullEnumTypeName(this, currentTypeScope, currentNamespaceScope) : currentTypeScope;
this.parentTypeFullName = typeRef.IsEnum ? typeRef.UpdateClrFullEnumTypeName(this, currentTypeScope, currentNamespaceScope, nestedEnumClassWasCreated) : currentTypeScope;
}

public void SetPropertyAttributes(CodeMemberProperty clrProperty, MemberAttributes visibility)
Expand Down Expand Up @@ -1176,18 +1187,28 @@ protected CodeExpression GetSimpleTypeClassExpression(bool disambiguateWhenPrope
{
Debug.Assert(this.simpleTypeClrTypeName.IsNotEmpty());

var areTheSameAndShouldDisambiguate = false;
if (disambiguateWhenPropertyAndTypeNameAreTheSame) {
if (this.propertyName == this.simpleTypeClrTypeName) {
areTheSameAndShouldDisambiguate = true;
bool areTheSameAndShouldDisambiguate = disambiguateWhenPropertyAndTypeNameAreTheSame || this.propertyName == this.simpleTypeClrTypeName;

string typeName;
if (areTheSameAndShouldDisambiguate)
{
string? possibleTypeNamespace = this.settings.GetClrNamespace(PropertyNs);
if (possibleTypeNamespace.IsEmpty())
{
possibleTypeNamespace = this.parentTypeFullName;
}
typeName = $"global::{possibleTypeNamespace}.{this.simpleTypeClrTypeName}";
}
else
{
typeName = this.simpleTypeClrTypeName;
}

string typeName = areTheSameAndShouldDisambiguate
? $"global::{this.settings.GetClrNamespace(PropertyNs)}.{this.simpleTypeClrTypeName}"
: this.simpleTypeClrTypeName;
if (!disambiguateWhenPropertyAndTypeNameAreTheSame && (this.typeRef.IsEnum && (this.typeRef.IsForAnonymousXsdType || this.typeRef.IsLocalType))) {
typeName = typeName.Split('.').Last();
}

var codeFieldReferenceExpression = CodeDomHelper.CreateFieldReference(typeName, Constants.SimpleTypeDefInnerType);
var codeFieldReferenceExpression = CodeDomHelper.CreateFieldReference(typeName + Constants.EnumValidator, Constants.SimpleTypeDefInnerType);

#if DEBUG
var str = codeFieldReferenceExpression.ToCodeString();
Expand Down
16 changes: 14 additions & 2 deletions XObjectsCode/Src/ClrTypeReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ public string Name
}
}

public string FullName
{
get {
if (LocalSuffix.IsNotEmpty()) {
return Name + LocalSuffix;
}

return Name;
}
}

public string? ClrName
{
get { return clrName; }
Expand Down Expand Up @@ -302,7 +313,8 @@ public string GetClrFullTypeName(
return clrTypeName;
}

internal string? UpdateClrFullEnumTypeName(ClrPropertyInfo property, string currentTypeScope, string currentNamespaceScope)
internal string? UpdateClrFullEnumTypeName(ClrPropertyInfo property, string currentTypeScope, string currentNamespaceScope,
bool nestedEnumClassCreated = false)
{
Debug.Assert(this.IsEnum);

Expand All @@ -315,7 +327,7 @@ public string GetClrFullTypeName(
else if (this.clrFullTypeName.IsEmpty())
{
//If the enum type is local (nested), use its parent type scope
if (property.TypeReference.IsLocalType)
if (property.TypeReference.IsLocalType || (property.TypeReference.IsForAnonymousXsdType || nestedEnumClassCreated))
this.clrFullTypeName = $"{currentTypeScope}.{this.ClrName ?? this.Name}";
else
this.clrFullTypeName = $"{theClrNamespace}.{this.ClrName ?? this.Name}";
Expand Down
22 changes: 12 additions & 10 deletions XObjectsCode/Src/TypeBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//Copyright (c) Microsoft Corporation. All rights reserved.

#nullable enable
using System;
using System.Xml;
using System.Xml.Schema;
Expand Down Expand Up @@ -404,23 +405,24 @@ internal static CodeTypeDeclaration CreateSimpleType(ClrSimpleTypeInfo typeInfo,
return simpleTypeDecl;
}

internal static CodeTypeDeclaration CreateEnumType(EnumSimpleTypeInfo typeInfo,
LinqToXsdSettings settings, ClrTypeInfo clrTypeInfo = null)
internal static CodeTypeDeclaration CreateEnumType(string clrTypeName, string clrTypeNs, XmlSchemaType innerType,
LinqToXsdSettings settings, ClrTypeInfo? clrTypeInfo = null)
{
string typeName = typeInfo.clrtypeName;

var enumTypeDecl = new CodeTypeDeclaration(typeName) { IsEnum = true };
var typeVisibility = settings.NamespaceTypesVisibilityMap.ValueForKey(typeInfo.clrtypeNs).ToTypeAttribute();
var enumTypeDecl = new CodeTypeDeclaration(clrTypeName) {
IsEnum = true
};
TypeAttributes typeVisibility = settings.NamespaceTypesVisibilityMap.ValueForKey(clrTypeNs).ToTypeAttribute();
enumTypeDecl.TypeAttributes = TypeAttributes.Sealed | typeVisibility;
foreach (var facet in typeInfo.InnerType.GetEnumFacets())
foreach (var facet in innerType.GetEnumFacets())
{
enumTypeDecl.Members.Add(new CodeMemberField(typeName, facet.Member));
enumTypeDecl.Members.Add(new CodeMemberField(clrTypeName, facet.Member));
}

if (clrTypeInfo != null)
{
enumTypeDecl.UserData[nameof(ClrTypeInfo)] = clrTypeInfo;

ApplyAnnotations(enumTypeDecl, typeInfo);
ApplyAnnotations(enumTypeDecl, clrTypeInfo);
}

return enumTypeDecl;
}
Expand Down
31 changes: 14 additions & 17 deletions XObjectsCode/Src/TypesToCodeDom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public IEnumerable<CodeNamespace> GenerateTypes(ClrMappingInfo binding)
if (stInfo != null)
{
if (stInfo is EnumSimpleTypeInfo enumTypeInfo) {
var enumType = TypeBuilder.CreateEnumType(enumTypeInfo, settings, stInfo);
var enumType = TypeBuilder.CreateEnumType(enumTypeInfo.clrtypeName, enumTypeInfo.clrtypeNs, enumTypeInfo.InnerType, settings, stInfo);
codeNamespace.AddTypeWithParentNamespace(enumType);
var enumsInOtherTypes = codeNamespace.DescendentTypeScopedEnumDeclarations();
// if an enum is defined in another type, remove it, if it is the same as the global (namespace scoped type)
Expand Down Expand Up @@ -187,7 +187,7 @@ private void ProcessProperties(IEnumerable<ContentInfo> properties, List<ClrAnno
{
ClrPropertyInfo propertyInfo = child as ClrPropertyInfo;
Debug.Assert(propertyInfo is not null);
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumType);
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumWithValidatorType);
typeBuilder.CreateAttributeProperty(propertyInfo, null);
}
else
Expand All @@ -207,7 +207,7 @@ private void ProcessProperties(IEnumerable<ContentInfo> properties, List<ClrAnno
}
}

private void CreateNestedEnumType(ClrTypeReference typeRef)
private void CreateNestedEnumWithValidatorType(ClrTypeReference typeRef, ClrTypeReference clrTypeInfo)
{
if (typeRef == null) throw new ArgumentNullException(nameof(typeRef));
var parentDecl = typeBuilder.TypeDeclaration;
Expand All @@ -218,20 +218,17 @@ private void CreateNestedEnumType(ClrTypeReference typeRef)
}

var innerType = typeRef.SchemaObject as XmlSchemaSimpleType;
Debug.Assert(innerType != null);
var visibilitySetting = this.settings.NamespaceTypesVisibilityMap.ValueForKey(typeRef.Namespace);
var enumTypeDecl = new CodeTypeDeclaration(typeRef.Name) {
IsEnum = true,
TypeAttributes = visibilitySetting.ToTypeAttribute()
Debug.Assert(innerType is not null);
var enumTypeInfo = new EnumSimpleTypeInfo(innerType) {
clrtypeName = typeRef.Name,
clrtypeNs = string.Empty,
IsNested = true
};
foreach (var facet in innerType.GetEnumFacets()) {
enumTypeDecl.Members.Add(new CodeMemberField(typeRef.Name, facet.Member));
}

enumTypeDecl.UserData[nameof(ClrTypeReference)] = typeRef;

Debug.Assert(innerType != null);
var enumTypeDecl = TypeBuilder.CreateEnumType(typeRef.Name, typeRef.Namespace, innerType, settings, null);

//Create enum validator type
var enumTypeInfo = new EnumSimpleTypeInfo(innerType) { clrtypeName = typeRef.Name, clrtypeNs = string.Empty };
var enumValidatorDecl = TypeBuilder.CreateSimpleType(enumTypeInfo, nameMappings, settings);

parentDecl.Members.Add(enumTypeDecl);
Expand Down Expand Up @@ -277,7 +274,7 @@ private void ProcessGroup(GroupingInfo grouping, List<ClrAnnotation> annotations
if (child.ContentType == ContentType.Property)
{
ClrPropertyInfo propertyInfo = child as ClrPropertyInfo;
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumType);
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumWithValidatorType);
typeBuilder.CreateProperty(propertyInfo, annotations);
}
else if (child.ContentType == ContentType.WildCardProperty)
Expand All @@ -302,7 +299,7 @@ private void ProcessComplexGroupProperties(GroupingInfo grouping, List<ClrAnnota
if (child.ContentType == ContentType.Property)
{
ClrPropertyInfo propertyInfo = child as ClrPropertyInfo;
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumType);
propertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumWithValidatorType);
typeBuilder.CreateProperty(propertyInfo, annotations);
}
else if (child.ContentType == ContentType.WildCardProperty)
Expand Down Expand Up @@ -744,7 +741,7 @@ private ClrPropertyInfo InitializeTypedValuePropertyInfo(ClrTypeInfo typeInfo,
existingTypedValPropertyInfo.IsNew = true;
}

existingTypedValPropertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumType);
existingTypedValPropertyInfo.UpdateTypeReference(currentFullTypeName, currentNamespace, nameMappings, CreateNestedEnumWithValidatorType);
return existingTypedValPropertyInfo;
}

Expand Down
Loading