protected override void VisitSelectSyntax(SelectSyntax pNode) { //Validate if a select is marked as complete, ensure all enum values are used if (pNode.Annotation.Value == KeyAnnotations.Complete) { var t = pNode.Condition.Type; if (!t.IsEnum) { CompilerErrors.CompleteNonEnum(pNode.Condition.Span); } else { //Get all enum values //We will indicate a field has been found by making the string null List <string> fields = new List <string>(); foreach (var f in t.GetFields()) { fields.Add(f.Name); } foreach (var c in pNode.Cases) { //Default covers all possible cases so mark all as found if (c.IsDefault) { for (int i = 0; i < fields.Count; i++) { fields[i] = null; } } else { foreach (var cd in c.Conditions) { //We can only check numeric literals and enum access //We cannot validate returning from a method if (cd is NumericLiteralSyntax n) { for (int i = 0; i < fields.Count; i++) { if (t.GetEnumValue(fields[i]) == int.Parse(n.Value)) { fields[i] = null; } } } else if (cd is MemberAccessSyntax m) { for (int i = 0; i < fields.Count; i++) { if (fields[i] == m.Value.Value) { fields[i] = null; } } } } } } fields = fields.Where((f) => f != null).ToList(); if (fields.Count > 0) { CompilerErrors.SelectComplete(fields.Aggregate(new StringBuilder(), (c, f) => { if (c.Length > 0) { c.Append(", "); } c.Append(f); return(c); }).ToString(), pNode.Span); } } } base.VisitSelectSyntax(pNode); }