private IEnumerable <DiagnosticRecord> FindHashtableViolations(TokenOperations tokenOps) { var hashtableAsts = tokenOps.Ast.FindAll(ast => ast is HashtableAst, true); var groups = new List <List <Tuple <IScriptExtent, IScriptExtent> > >(); if (hashtableAsts != null) { foreach (var astItem in hashtableAsts) { groups.Add(GetExtents(tokenOps, (HashtableAst)astItem)); } } #if !PSV3 var configAsts = tokenOps.Ast.FindAll(ast => ast is ConfigurationDefinitionAst, true); if (configAsts != null) { // There are probably parse errors caused by an "Undefined DSC resource" // which prevents the parser from detecting the property value pairs as // hashtable. Hence, this is a workaround to format configurations which // have "Undefined DSC resource" parse errors. // find all commandAsts of the form "prop" "=" "val" that have the same parent // and format those pairs. foreach (var configAst in configAsts) { groups.AddRange(GetCommandElementExtentGroups(configAst)); } } #endif // it is probably much easier have a hashtable writer that formats the hashtable and writes it // but it makes handling comments hard. So we need to use this approach. // This is how the algorithm actually works: // if each key value pair are on a separate line // find all the assignment operators // if all the assignment operators are aligned (check the column number of each assignment operator) // skip // else // find the distance between the assignment operators and their corresponding LHS // find the longest left expression // make sure all the assignment operators are in the same column as that of the longest left hand. foreach (var extentTuples in groups) { if (!HasPropertiesOnSeparateLines(extentTuples)) { continue; } if (extentTuples == null || extentTuples.Count == 0 || !extentTuples.All(t => t.Item1.StartLineNumber == t.Item2.EndLineNumber)) { continue; } var widestKeyExtent = extentTuples .Select(t => t.Item1) .Aggregate((t1, tAggregate) => { return(TokenOperations.GetExtentWidth(tAggregate) > TokenOperations.GetExtentWidth(t1) ? tAggregate : t1); }); var expectedStartColumnNumber = widestKeyExtent.EndColumnNumber + 1; foreach (var extentTuple in extentTuples) { if (extentTuple.Item2.StartColumnNumber != expectedStartColumnNumber) { yield return(new DiagnosticRecord( GetError(), extentTuple.Item2, GetName(), GetDiagnosticSeverity(), extentTuple.Item1.File, null, GetHashtableCorrections(extentTuple, expectedStartColumnNumber).ToList())); } } } }
private IEnumerable <DiagnosticRecord> FindHashtableViolations(TokenOperations tokenOps) { var hashtableAsts = tokenOps.Ast.FindAll(ast => ast is HashtableAst, true); if (hashtableAsts == null) { yield break; } // it is probably much easier have a hashtable writer that formats the hashtable and writes it // but it makes handling comments hard. So we need to use this approach. // This is how the algorithm actually works: // if each key value pair are on a separate line // find all the assignment operators // if all the assignment operators are aligned (check the column number of each assignment operator) // skip // else // find the distance between the assignment operators and their corresponding LHS // find the longest left expression // make sure all the assignment operators are in the same column as that of the longest left hand. foreach (var astItem in hashtableAsts) { var hashtableAst = (HashtableAst)astItem; if (!HasKeysOnSeparateLines(hashtableAst)) { continue; } var extentTuples = GetExtents(tokenOps, hashtableAst); if (extentTuples == null || extentTuples.Count == 0 || !extentTuples.All(t => t.Item1.StartLineNumber == t.Item2.EndLineNumber)) { continue; } var widestKeyExtent = extentTuples .Select(t => t.Item1) .Aggregate((t1, tAggregate) => { return(TokenOperations.GetExtentWidth(tAggregate) > TokenOperations.GetExtentWidth(t1) ? tAggregate : t1); }); var expectedStartColumnNumber = widestKeyExtent.EndColumnNumber + 1; foreach (var extentTuple in extentTuples) { if (extentTuple.Item2.StartColumnNumber != expectedStartColumnNumber) { yield return(new DiagnosticRecord( GetError(), extentTuple.Item2, GetName(), GetDiagnosticSeverity(), extentTuple.Item1.File, null, GetHashtableCorrections(extentTuple, expectedStartColumnNumber).ToList())); } } } }