in src/lib/Microsoft.Fx.Portability/BreakingChangeParser.cs [237:370]
private static void ParseNonStateChange(BreakingChange currentBreak, ParseState state, string currentLine, IEnumerable<string> allowedCategories)
{
switch (state)
{
case ParseState.None:
return;
case ParseState.OriginalBug:
if (string.IsNullOrEmpty(currentBreak.BugLink))
{
currentBreak.BugLink = currentLine.Trim();
}
break;
case ParseState.Scope:
BreakingChangeImpact scope;
if (Enum.TryParse<BreakingChangeImpact>(currentLine.Trim(), out scope))
{
currentBreak.ImpactScope = scope;
}
break;
case ParseState.VersionBroken:
Version verBroken;
if (Version.TryParse(currentLine.Trim(), out verBroken))
{
currentBreak.VersionBroken = verBroken;
}
break;
case ParseState.VersionFixed:
Version verFixed;
if (Version.TryParse(currentLine.Trim(), out verFixed))
{
currentBreak.VersionFixed = verFixed;
}
break;
case ParseState.AffectedAPIs:
// Trim md list and code markers, as well as comment tags (in case the affected APIs section is followed by a comment)
string api = currentLine.Trim().TrimStart('*', '-', '`', ' ', '\t', '<', '!', '-').TrimEnd('`');
if (string.IsNullOrWhiteSpace(api))
{
return;
}
if (currentBreak.ApplicableApis == null)
{
currentBreak.ApplicableApis = new List<string>();
}
if (!IgnoredApis.Contains(api))
{
currentBreak.ApplicableApis.Add(api);
}
break;
case ParseState.Details:
if (currentBreak.Details == null)
{
currentBreak.Details = currentLine;
}
else
{
currentBreak.Details += "\n" + currentLine;
}
break;
case ParseState.Suggestion:
if (currentBreak.Suggestion == null)
{
currentBreak.Suggestion = currentLine;
}
else
{
currentBreak.Suggestion += "\n" + currentLine;
}
break;
case ParseState.Notes:
// Special-case the fact that 'notes' will often come at the end of a comment section and we don't need the closing --> in the note.
if (string.Equals("-->", currentLine.Trim(), StringComparison.Ordinal))
{
return;
}
if (currentBreak.Notes == null)
{
currentBreak.Notes = currentLine;
}
else
{
currentBreak.Notes += "\n" + currentLine;
}
break;
case ParseState.SourceAnalyzerStatus:
if (Enum.TryParse<BreakingChangeAnalyzerStatus>(currentLine.Trim().Replace(" ", string.Empty), true, out var status))
{
currentBreak.SourceAnalyzerStatus = status;
}
break;
case ParseState.Categories:
if (string.IsNullOrWhiteSpace(currentLine) || currentLine.StartsWith("<!--", StringComparison.Ordinal))
{
break;
}
// If a list of allowed categories was provided, make sure that the category found is on the list
if (!allowedCategories?.Contains(currentLine, StringComparer.OrdinalIgnoreCase) ?? false)
{
throw new InvalidOperationException(
string.Format(CultureInfo.CurrentCulture, LocalizedStrings.InvalidCategoryDetected, currentLine));
}
if (currentBreak.Categories == null)
{
currentBreak.Categories = new List<string>();
}
currentBreak.Categories.Add(currentLine);
break;
case ParseState.Comment:
// ignore multi-line comments
if (currentLine.EndsWith("-->", StringComparison.Ordinal))
{
state = ParseState.None;
}
break;
default:
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, LocalizedStrings.InvalidBreakingChangeParserState, state.ToString()));
}
}