提交 50f8500d 编写于 作者: N Nick Guerrera

Prevent duplicate rule metadata in /errorlog

上级 fab958dc
......@@ -93,10 +93,25 @@ public void AdditionalLocationsAsRelatedLocations()
public void DescriptorIdCollision()
{
var descriptors = new[] {
// Toughest case: generation of TST001.001 collides with with actual TST001.001 and must be bumped to TST00.002
new DiagnosticDescriptor("TST001.001", "_TST001.001_", "", "", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST001", "_TST001_", "", "", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST001", "_TST001.002_", "", "", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST001", "_TST001.003_", "", "", DiagnosticSeverity.Warning, true),
// Descriptors with same values should not get distinct entries in log
new DiagnosticDescriptor("TST002", "", "", "", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST002", "", "", "", DiagnosticSeverity.Warning, true),
// Changing only the message format (which we do not write out) should not produce a distinct entry in log.
new DiagnosticDescriptor("TST002", "", "messageFormat", "", DiagnosticSeverity.Warning, true),
// Changing any property that we do write out should create a distinct entry
new DiagnosticDescriptor("TST002", "title_001", "", "", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST002", "", "", "category_002", DiagnosticSeverity.Warning, true),
new DiagnosticDescriptor("TST002", "", "", "", DiagnosticSeverity.Error /*003*/, true),
new DiagnosticDescriptor("TST002", "", "", "", DiagnosticSeverity.Warning, isEnabledByDefault: false /*004*/),
new DiagnosticDescriptor("TST002", "", "", "", DiagnosticSeverity.Warning, true, "description_005"),
};
var stream = new MemoryStream();
......@@ -154,6 +169,65 @@ public void DescriptorIdCollision()
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""message"": ""messageFormat"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.001"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.003"",
""level"": ""error""
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.004"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.005"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST001.001"",
""level"": ""warning"",
......@@ -183,6 +257,65 @@ public void DescriptorIdCollision()
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""level"": ""warning"",
""message"": ""messageFormat"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.001"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.002"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.003"",
""level"": ""error""
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.004"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
},
{
""ruleId"": ""TST002"",
""ruleKey"": ""TST002.005"",
""level"": ""warning"",
""properties"": {
""warningLevel"": 1
}
}
],
""rules"": {
......@@ -217,6 +350,51 @@ public void DescriptorIdCollision()
""properties"": {
""isEnabledByDefault"": true
}
},
""TST002"": {
""id"": ""TST002"",
""defaultLevel"": ""warning"",
""properties"": {
""isEnabledByDefault"": true
}
},
""TST002.001"": {
""id"": ""TST002"",
""shortDescription"": ""title_001"",
""defaultLevel"": ""warning"",
""properties"": {
""isEnabledByDefault"": true
}
},
""TST002.002"": {
""id"": ""TST002"",
""defaultLevel"": ""warning"",
""properties"": {
""category"": ""category_002"",
""isEnabledByDefault"": true
}
},
""TST002.003"": {
""id"": ""TST002"",
""defaultLevel"": ""error"",
""properties"": {
""isEnabledByDefault"": true
}
},
""TST002.004"": {
""id"": ""TST002"",
""defaultLevel"": ""warning"",
""properties"": {
""isEnabledByDefault"": false
}
},
""TST002.005"": {
""id"": ""TST002"",
""fullDescription"": ""description_005"",
""defaultLevel"": ""warning"",
""properties"": {
""isEnabledByDefault"": true
}
}
}
}
......
......@@ -317,7 +317,7 @@ private sealed class DiagnosticDescriptorSet
private Dictionary<string, int> _counters = new Dictionary<string, int>();
// DiagnosticDescriptor -> unique key
private Dictionary<DiagnosticDescriptor, string> _keys = new Dictionary<DiagnosticDescriptor, string>();
private Dictionary<DiagnosticDescriptor, string> _keys = new Dictionary<DiagnosticDescriptor, string>(new Comparer());
/// <summary>
/// The total number of descriptors in the set.
......@@ -381,6 +381,54 @@ public string Add(DiagnosticDescriptor descriptor)
list.Sort((x, y) => string.CompareOrdinal(x.Key, y.Key));
return list;
}
/// <summary>
/// Compares descriptors by the values that we write to the log and nothing else.
///
/// We cannot use the IEquatable implementation because it includes message format
/// and we don't write it out. It also ignores tags, which we do write.
/// </summary>
private sealed class Comparer : IEqualityComparer<DiagnosticDescriptor>
{
public bool Equals(DiagnosticDescriptor x, DiagnosticDescriptor y)
{
if (ReferenceEquals(x, y))
return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false;
return (x.Category == y.Category
&& x.DefaultSeverity == y.DefaultSeverity
&& x.Description.Equals(y.Description)
&& x.HelpLinkUri == y.HelpLinkUri
&& x.Id == y.Id
&& x.IsEnabledByDefault == y.IsEnabledByDefault
&& x.Title.Equals(y.Title)
&& x.CustomTags.SequenceEqual(y.CustomTags));
}
public int GetHashCode(DiagnosticDescriptor obj)
{
if (ReferenceEquals(obj, null))
return 0;
int hash = Hash.Combine(obj.Category.GetHashCode(),
Hash.Combine(obj.DefaultSeverity.GetHashCode(),
Hash.Combine(obj.Description.GetHashCode(),
Hash.Combine(obj.HelpLinkUri.GetHashCode(),
Hash.Combine(obj.Id.GetHashCode(),
Hash.Combine(obj.IsEnabledByDefault.GetHashCode(),
obj.Title.GetHashCode()))))));
foreach (string tag in obj.CustomTags)
{
hash = Hash.Combine(tag, hash);
}
return hash;
}
}
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册