diff --git a/Design/Rule0044AnalyzeTransferField.cs b/Design/Rule0044AnalyzeTransferField.cs index c33994f1..2e9f89d8 100644 --- a/Design/Rule0044AnalyzeTransferField.cs +++ b/Design/Rule0044AnalyzeTransferField.cs @@ -1,6 +1,7 @@ using Microsoft.Dynamics.Nav.CodeAnalysis; using Microsoft.Dynamics.Nav.CodeAnalysis.Diagnostics; using Microsoft.Dynamics.Nav.CodeAnalysis.Syntax; +using Microsoft.Dynamics.Nav.CodeAnalysis.Utilities; using System.Collections.Immutable; using System.Reflection; @@ -393,11 +394,13 @@ private bool DifferentNameAndTypeFilter(IGrouping fieldGroup) { string name = fieldGroup.First().Name; string type = fieldGroup.First().Type; + FieldClassKind fieldClass = fieldGroup.First().FieldClass; - foreach (Field field in fieldGroup) + foreach (Field field in fieldGroup.Where(fld => fld.FieldClass == FieldClassKind.Normal)) { - if (!(name.Equals(field.Name) && type.Equals(field.Type))) - return true; + if (fieldClass == FieldClassKind.Normal && field.FieldClass == FieldClassKind.Normal) + if (!(name.Equals(field.Name) && type.Equals(field.Type))) + return true; } return false; @@ -673,14 +676,16 @@ public class Field public string Type { get; } public Microsoft.Dynamics.Nav.CodeAnalysis.Text.Location? Location { get; } public Table Table { get; } + public FieldClassKind FieldClass { get; } - public Field(int id, string name, string type, Microsoft.Dynamics.Nav.CodeAnalysis.Text.Location? location, Table table) + public Field(int id, string name, string type, Microsoft.Dynamics.Nav.CodeAnalysis.Text.Location? location, Table table, FieldClassKind fieldClass) { Id = id; Name = name; Type = type; Location = location; Table = table; + FieldClass = fieldClass; } } @@ -715,19 +720,25 @@ public void PopulateFields(IApplicationObjectTypeSymbol table) PropertyInfo idprop = type.GetProperty("Id", BindingFlags.Instance | BindingFlags.Public); PropertyInfo nameprop = type.GetProperty("Name", BindingFlags.Instance | BindingFlags.Public); PropertyInfo typeprop = type.GetProperty("Type", BindingFlags.Instance | BindingFlags.Public); - PropertyInfo namespaceProp = type.GetProperty("ContainingNamespace", BindingFlags.Instance | BindingFlags.Public); + PropertyInfo fieldClassProp = type.GetProperty("FieldClass", BindingFlags.Instance | BindingFlags.Public); int id = (int)idprop.GetValue(field); string name = (string)nameprop.GetValue(field); string objtype = typeprop.GetValue(field).ToString(); - string objNamespace = namespaceProp.GetValue(field).ToString(); + string fieldClass = fieldClassProp.GetValue(field).ToString(); - int namespaceIndex = objtype.IndexOf(objNamespace + '.'); - if (namespaceIndex != -1) - objtype = objtype.Remove(namespaceIndex, objNamespace.Length + 1); + // Remove the QualifiedName from the Enum for now. + // In the future refactor this to support Enums with the same object name cross different namespaces + IEnumBaseTypeSymbol? enumBaseTypeSymbol = typeprop.GetValue(field) as IEnumBaseTypeSymbol; + if (enumBaseTypeSymbol != null) + { + INamespaceSymbol? namespaceSymbol = enumBaseTypeSymbol.ContainingSymbol as INamespaceSymbol; + if (namespaceSymbol != null) + objtype = objtype.Replace(namespaceSymbol.QualifiedName + '.', ""); + } if (id < 2000000000) - Fields.Add(new Field(id, name, objtype, null, this)); + Fields.Add(new Field(id, name, objtype, null, this, GetFieldClass(fieldClass))); } } @@ -738,7 +749,7 @@ public void PopulateFields(FieldExtensionListSyntax fieldList) foreach (FieldSyntax field in fieldList.Fields.Where(fld => fld.IsKind(SyntaxKind.Field))) { if (!FieldIsObsolete(field)) - Fields.Add(new Field((int)field.No.Value, field.Name.Identifier.ToString().Replace("\"", ""), field.Type.ToString(), field.GetLocation(), this)); + Fields.Add(new Field((int)field.No.Value, field.Name.Identifier.ValueText.UnquoteIdentifier(), field.Type.ToString(), field.GetLocation(), this, GetFieldClass(field))); } } @@ -749,7 +760,7 @@ public void PopulateFields(FieldListSyntax fieldList) foreach (FieldSyntax field in fieldList.Fields) { if (!FieldIsObsolete(field)) - Fields.Add(new Field((int)field.No.Value, field.Name.Identifier.ToString().Replace("\"", ""), field.Type.ToString(), field.GetLocation(), this)); + Fields.Add(new Field((int)field.No.Value, field.Name.Identifier.ValueText.UnquoteIdentifier(), field.Type.ToString(), field.GetLocation(), this, GetFieldClass(field))); } } @@ -771,6 +782,32 @@ private bool FieldIsObsolete(FieldSyntax field) return false; } + + private FieldClassKind GetFieldClass(FieldSyntax field) + { + PropertySyntax fieldClassProperty = (PropertySyntax)field.PropertyList.Properties.Where(prop => !prop.IsKind(SyntaxKind.EmptyProperty)) + .Where(prop => ((PropertySyntax)prop).Name.Identifier.ToString().Equals("FieldClass")) + .Where(prop => ((PropertySyntax)prop).Value.GetType() == typeof(EnumPropertyValueSyntax)) + .SingleOrDefault(); + if (fieldClassProperty == null) + return FieldClassKind.Normal; + + EnumPropertyValueSyntax fieldClassPropertyValue = (EnumPropertyValueSyntax)fieldClassProperty.Value; + return GetFieldClass(fieldClassPropertyValue.Value.Identifier.ValueText.UnquoteIdentifier()); + } + + private FieldClassKind GetFieldClass(string fieldClass) + { + switch (fieldClass) + { + case "FlowField": + return FieldClassKind.FlowField; + case "FlowFilter": + return FieldClassKind.FlowFilter; + default: + return FieldClassKind.Normal; + } + } } } } \ No newline at end of file