Fix #2298 simplify TagHelperDescriptor hash
The hash code implementation here is exhaustive when it doesn't need to be. Slimming this down to a much more reasonable set of things for perf reasons.
This commit is contained in:
parent
2885b4b138
commit
f67458f156
|
|
@ -54,20 +54,18 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return false;
|
||||
}
|
||||
|
||||
return descriptorX != null &&
|
||||
return
|
||||
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics);
|
||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual int GetHashCode(AllowedChildTagDescriptor descriptor)
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
|
||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(descriptor.Name, _stringComparer);
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return false;
|
||||
}
|
||||
|
||||
return descriptorX != null &&
|
||||
return
|
||||
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
||||
descriptorX.IsIndexerStringProperty == descriptorY.IsIndexerStringProperty &&
|
||||
descriptorX.IsEnum == descriptorY.IsEnum &&
|
||||
|
|
@ -61,7 +61,6 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
string.Equals(descriptorX.IndexerTypeName, descriptorY.IndexerTypeName, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics) &&
|
||||
Enumerable.SequenceEqual(
|
||||
descriptorX.Metadata.OrderBy(propertyX => propertyX.Key, StringComparer.Ordinal),
|
||||
descriptorY.Metadata.OrderBy(propertyY => propertyY.Key, StringComparer.Ordinal));
|
||||
|
|
@ -74,19 +73,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
throw new ArgumentNullException(nameof(descriptor));
|
||||
}
|
||||
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(descriptor.Kind);
|
||||
hashCodeCombiner.Add(descriptor.IsIndexerStringProperty);
|
||||
hashCodeCombiner.Add(descriptor.IsEnum);
|
||||
hashCodeCombiner.Add(descriptor.HasIndexer);
|
||||
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
|
||||
hashCodeCombiner.Add(descriptor.IndexerNamePrefix, _stringComparer);
|
||||
hashCodeCombiner.Add(descriptor.TypeName, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.IndexerTypeName, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.Documentation, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(descriptor.Kind);
|
||||
hash.Add(descriptor.Name, _stringComparer);
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Language
|
||||
|
|
@ -58,26 +57,21 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return false;
|
||||
}
|
||||
|
||||
return descriptorX != null &&
|
||||
return
|
||||
descriptorX.NameComparison == descriptorY.NameComparison &&
|
||||
descriptorX.ValueComparison == descriptorY.ValueComparison &&
|
||||
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
||||
string.Equals(descriptorX.Value, descriptorY.Value, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics);
|
||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual int GetHashCode(RequiredAttributeDescriptor descriptor)
|
||||
{
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(descriptor.NameComparison);
|
||||
hashCodeCombiner.Add(descriptor.ValueComparison);
|
||||
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
|
||||
hashCodeCombiner.Add(descriptor.Value, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(descriptor.Name, _stringComparer);
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
|
||||
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||
{
|
||||
if (descriptorX == descriptorY)
|
||||
if (object.ReferenceEquals(descriptorX, descriptorY))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -62,6 +62,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return descriptorX != null &&
|
||||
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal) &&
|
||||
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) &&
|
||||
Enumerable.SequenceEqual(
|
||||
descriptorX.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer),
|
||||
descriptorY.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer),
|
||||
|
|
@ -94,33 +95,12 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
throw new ArgumentNullException(nameof(descriptor));
|
||||
}
|
||||
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(descriptor.Kind);
|
||||
hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal);
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(descriptor.Kind, StringComparer.Ordinal);
|
||||
hash.Add(descriptor.AssemblyName, StringComparer.Ordinal);
|
||||
hash.Add(descriptor.Name, StringComparer.Ordinal);
|
||||
|
||||
var childTags = descriptor.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer);
|
||||
foreach (var childTag in childTags)
|
||||
{
|
||||
hashCodeCombiner.Add(_AllowedChildTagDescriptorComparer.GetHashCode(childTag));
|
||||
}
|
||||
|
||||
var boundAttributes = descriptor.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer);
|
||||
foreach (var attribute in boundAttributes)
|
||||
{
|
||||
hashCodeCombiner.Add(_boundAttributeComparer.GetHashCode(attribute));
|
||||
}
|
||||
|
||||
var rules = descriptor.TagMatchingRules.OrderBy(rule => rule.TagName, _stringComparer);
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
hashCodeCombiner.Add(_tagMatchingRuleComparer.GetHashCode(rule));
|
||||
}
|
||||
|
||||
hashCodeCombiner.Add(descriptor.Documentation, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
||||
hashCodeCombiner.Add(descriptor.TagOutputHint, _stringComparer);
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -54,12 +54,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
return false;
|
||||
}
|
||||
|
||||
return ruleX != null &&
|
||||
return
|
||||
string.Equals(ruleX.TagName, ruleY.TagName, _stringComparison) &&
|
||||
string.Equals(ruleX.ParentTag, ruleY.ParentTag, _stringComparison) &&
|
||||
ruleX.TagStructure == ruleY.TagStructure &&
|
||||
Enumerable.SequenceEqual(ruleX.Attributes, ruleY.Attributes, _requiredAttributeComparer) &&
|
||||
Enumerable.SequenceEqual(ruleX.Diagnostics, ruleY.Diagnostics);
|
||||
Enumerable.SequenceEqual(ruleX.Attributes, ruleY.Attributes, _requiredAttributeComparer);
|
||||
}
|
||||
|
||||
public virtual int GetHashCode(TagMatchingRuleDescriptor rule)
|
||||
|
|
@ -69,18 +68,10 @@ namespace Microsoft.AspNetCore.Razor.Language
|
|||
throw new ArgumentNullException(nameof(rule));
|
||||
}
|
||||
|
||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
||||
hashCodeCombiner.Add(rule.TagName, _stringComparer);
|
||||
hashCodeCombiner.Add(rule.ParentTag, _stringComparer);
|
||||
hashCodeCombiner.Add(rule.TagStructure);
|
||||
var hash = HashCodeCombiner.Start();
|
||||
hash.Add(rule.TagName, _stringComparer);
|
||||
|
||||
var attributes = rule.Attributes.OrderBy(attribute => attribute.Name, _stringComparer);
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
hashCodeCombiner.Add(_requiredAttributeComparer.GetHashCode(attribute));
|
||||
}
|
||||
|
||||
return hashCodeCombiner.CombinedHash;
|
||||
return hash.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,18 +29,16 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
|||
_tagHelperFactsService = tagHelperFactsService;
|
||||
}
|
||||
|
||||
/*
|
||||
* This API attempts to understand a users context as they're typing in a Razor file to provide TagHelper based attribute IntelliSense.
|
||||
*
|
||||
* Scenarios for TagHelper attribute IntelliSense follows:
|
||||
* 1. TagHelperDescriptor's have matching required attribute names
|
||||
* -> Provide IntelliSense for the required attributes of those descriptors to lead users towards a TagHelperified element.
|
||||
* 2. TagHelperDescriptor entirely applies to current element. Tag name, attributes, everything is fulfilled.
|
||||
* -> Provide IntelliSense for the bound attributes for the applied descriptors.
|
||||
*
|
||||
* Within each of the above scenarios if an attribute completion has a corresponding bound attribute we associate it with the corresponding
|
||||
* BoundAttributeDescriptor. By doing this a user can see what C# type a TagHelper expects for the attribute.
|
||||
*/
|
||||
// This API attempts to understand a users context as they're typing in a Razor file to provide TagHelper based attribute IntelliSense.
|
||||
//
|
||||
// Scenarios for TagHelper attribute IntelliSense follows:
|
||||
// 1. TagHelperDescriptor's have matching required attribute names
|
||||
// -> Provide IntelliSense for the required attributes of those descriptors to lead users towards a TagHelperified element.
|
||||
// 2. TagHelperDescriptor entirely applies to current element. Tag name, attributes, everything is fulfilled.
|
||||
// -> Provide IntelliSense for the bound attributes for the applied descriptors.
|
||||
//
|
||||
// Within each of the above scenarios if an attribute completion has a corresponding bound attribute we associate it with the corresponding
|
||||
// BoundAttributeDescriptor. By doing this a user can see what C# type a TagHelper expects for the attribute.
|
||||
public override AttributeCompletionResult GetAttributeCompletions(AttributeCompletionContext completionContext)
|
||||
{
|
||||
if (completionContext == null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue