Skip to content

Commit 3409aa0

Browse files
authored
Merge pull request #508 from BHoM/CodeComplianceTest_Engine-#505-FixIncompleteComplianceChecks
Tweaks to compliance checks to handle edge cases
2 parents 8454c95 + ace1be2 commit 3409aa0

File tree

3 files changed

+51
-26
lines changed

3 files changed

+51
-26
lines changed

CodeComplianceTest_Engine/Query/Checks/HasUniqueMultiOutputAttributes.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public static Span HasUniqueMultiOutputAttributes(this MethodDeclarationSyntax n
6868
string builtString = "";
6969
foreach (char x in returnType)
7070
{
71-
if (x == '<')
71+
if (x == '<' || x == '[')
7272
split++;
7373

74-
if (x == '>')
74+
if (x == '>' || x == ']')
7575
split--;
7676

7777
if (x == ',' && split == 0)
@@ -91,7 +91,7 @@ public static Span HasUniqueMultiOutputAttributes(this MethodDeclarationSyntax n
9191
string t = x.ToString();
9292
string newString = "";
9393
int bracketCount = 0;
94-
foreach(char i in t)
94+
foreach (char i in t)
9595
{
9696
if (i == '<')
9797
bracketCount++;

CodeComplianceTest_Engine/Query/Checks/HasValidMultiOutputAttributes.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public static Span HasValidMultiOutputAttributes(this MethodDeclarationSyntax no
6868
string builtString = "";
6969
foreach (char x in returnType)
7070
{
71-
if (x == '<')
71+
if (x == '<' || x == '[')
7272
split++;
7373

74-
if(x == '>')
74+
if (x == '>' || x == ']')
7575
split--;
7676

7777
if (x == ',' && split == 0)

CodeComplianceTest_Engine/Query/Checks/IsValidCreateMethod.cs

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,38 +47,63 @@ public static Span IsValidCreateMethod(this MethodDeclarationSyntax node)
4747
return null;
4848

4949
string filePath = node.SyntaxTree.FilePath;
50+
51+
if (string.IsNullOrEmpty(filePath))
52+
return node.Identifier.Span.ToSpan();
53+
54+
//Split the path, including the filename.
55+
//Split by dot to get rid of extension in .cs file.
56+
//Reverse to start with file and walk backwards
57+
List<string> pathSplit = filePath.Split(System.IO.Path.DirectorySeparatorChar).Select(x => x.Split('.').First()).Reverse().ToList();
58+
59+
foreach (string returnType in ReturnTypeCandidates(node))
60+
{
61+
foreach (string path in pathSplit)
62+
{
63+
if (path == "Create") //Loop until we reach the create folder
64+
break;
65+
66+
if (Regex.Match(returnType, $"((List|IEnumerable)<)?I?{path}(<.*>)?>?$").Success)
67+
return null; //Name of file or folder matches return type exactly so this is valid. IsValidCreateMethodName will check if the method name matches the file name
68+
}
69+
}
70+
return node.Identifier.Span.ToSpan(); //Create method file (name/path) and return type do not match as required
71+
}
72+
73+
private static List<string> ReturnTypeCandidates(this MethodDeclarationSyntax node)
74+
{
75+
List<string> returnTypeNames = new List<string>();
76+
5077
var type = node.ReturnType;
5178
if (type is QualifiedNameSyntax)
5279
type = ((QualifiedNameSyntax)type).Right;
53-
80+
5481
string returnType = type.ToString();
55-
string fileName = "";
5682

57-
if(!string.IsNullOrEmpty(filePath))
83+
returnTypeNames.Add(returnType);
84+
85+
//Handle the case where the method returns a generic type.
86+
//Then check the constraints of the generic type, if any of them matches the file name, then that is also acceptable
87+
if (node.ConstraintClauses.Count != 0)
5888
{
59-
fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
60-
if(Regex.Match(returnType, $"((List|IEnumerable)<)?I?{fileName}(<.*>)?>?$").Success)
61-
return null; //File name matches return type exactly so this is valid. IsValidCreateMethodName will check if the method name matches the file name
62-
}
89+
foreach (var constraintClause in node.ConstraintClauses)
90+
{
91+
string constraintString = constraintClause.ToString(); //where T : XXX, YYY
92+
string[] split = constraintString.Split(':');
93+
if (split.Length != 2)
94+
continue;
6395

64-
//If file name does not exactly match the return type then we need to check if the return type is in a sub-folder in create
96+
string target = split[0].Trim().Split(' ').Last().Trim(); //Split with space to get rid of where
6597

66-
List<string> pathSplit = filePath.Split(System.IO.Path.DirectorySeparatorChar).ToList();
67-
int createIndex = pathSplit.IndexOf("Create");
68-
if (createIndex == -1)
69-
return node.Identifier.Span.ToSpan(); //Evidently this create method isn't working for some reason - even though it should but this is as a protection/precaution
98+
if (target != returnType)
99+
continue;
70100

71-
try
72-
{
73-
if (Regex.Match(returnType, $"((List|IEnumerable)<)?I?{pathSplit[createIndex + 1]}(<.*>)?>?$").Success || Regex.Match(returnType, $"((List|IEnumerable)<)?I?{pathSplit[createIndex + 2]}(<.*>)?>?$").Success)
74-
return null; //The folder path after the 'Create' folder matches the return type so this is valid. IsValidCreateMethodName will check if the method name matches the file name
75-
}
76-
catch
77-
{
78-
//In case createIndex + 1 || createIndex + 2 result in an out of bounds error - it means the check has failed and something isn't compliant so can pass through to returning the span
101+
returnTypeNames.AddRange(split[1].Split(',').Select(x => x.Trim()));
102+
}
79103
}
80104

81-
return node.Identifier.Span.ToSpan(); //Create method file (name/path) and return type do not match as required
105+
106+
return returnTypeNames;
82107
}
83108
}
84109
}

0 commit comments

Comments
 (0)