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 false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return descriptorX != null &&
|
return
|
||||||
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
||||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal);
|
||||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual int GetHashCode(AllowedChildTagDescriptor descriptor)
|
public virtual int GetHashCode(AllowedChildTagDescriptor descriptor)
|
||||||
{
|
{
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
var hash = HashCodeCombiner.Start();
|
||||||
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
|
hash.Add(descriptor.Name, _stringComparer);
|
||||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
|
||||||
|
|
||||||
return hashCodeCombiner.CombinedHash;
|
return hash.CombinedHash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return descriptorX != null &&
|
return
|
||||||
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
||||||
descriptorX.IsIndexerStringProperty == descriptorY.IsIndexerStringProperty &&
|
descriptorX.IsIndexerStringProperty == descriptorY.IsIndexerStringProperty &&
|
||||||
descriptorX.IsEnum == descriptorY.IsEnum &&
|
descriptorX.IsEnum == descriptorY.IsEnum &&
|
||||||
|
|
@ -61,7 +61,6 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
string.Equals(descriptorX.IndexerTypeName, descriptorY.IndexerTypeName, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.IndexerTypeName, descriptorY.IndexerTypeName, StringComparison.Ordinal) &&
|
||||||
string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.Documentation, descriptorY.Documentation, StringComparison.Ordinal) &&
|
||||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
||||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics) &&
|
|
||||||
Enumerable.SequenceEqual(
|
Enumerable.SequenceEqual(
|
||||||
descriptorX.Metadata.OrderBy(propertyX => propertyX.Key, StringComparer.Ordinal),
|
descriptorX.Metadata.OrderBy(propertyX => propertyX.Key, StringComparer.Ordinal),
|
||||||
descriptorY.Metadata.OrderBy(propertyY => propertyY.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));
|
throw new ArgumentNullException(nameof(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
var hash = HashCodeCombiner.Start();
|
||||||
hashCodeCombiner.Add(descriptor.Kind);
|
hash.Add(descriptor.Kind);
|
||||||
hashCodeCombiner.Add(descriptor.IsIndexerStringProperty);
|
hash.Add(descriptor.Name, _stringComparer);
|
||||||
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);
|
|
||||||
|
|
||||||
return hashCodeCombiner.CombinedHash;
|
return hash.CombinedHash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Razor.Language
|
namespace Microsoft.AspNetCore.Razor.Language
|
||||||
|
|
@ -58,26 +57,21 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return descriptorX != null &&
|
return
|
||||||
descriptorX.NameComparison == descriptorY.NameComparison &&
|
descriptorX.NameComparison == descriptorY.NameComparison &&
|
||||||
descriptorX.ValueComparison == descriptorY.ValueComparison &&
|
descriptorX.ValueComparison == descriptorY.ValueComparison &&
|
||||||
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
string.Equals(descriptorX.Name, descriptorY.Name, _stringComparison) &&
|
||||||
string.Equals(descriptorX.Value, descriptorY.Value, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.Value, descriptorY.Value, StringComparison.Ordinal) &&
|
||||||
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.DisplayName, descriptorY.DisplayName, StringComparison.Ordinal);
|
||||||
Enumerable.SequenceEqual(descriptorX.Diagnostics, descriptorY.Diagnostics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public virtual int GetHashCode(RequiredAttributeDescriptor descriptor)
|
public virtual int GetHashCode(RequiredAttributeDescriptor descriptor)
|
||||||
{
|
{
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
var hash = HashCodeCombiner.Start();
|
||||||
hashCodeCombiner.Add(descriptor.NameComparison);
|
hash.Add(descriptor.Name, _stringComparer);
|
||||||
hashCodeCombiner.Add(descriptor.ValueComparison);
|
|
||||||
hashCodeCombiner.Add(descriptor.Name, _stringComparer);
|
|
||||||
hashCodeCombiner.Add(descriptor.Value, StringComparer.Ordinal);
|
|
||||||
hashCodeCombiner.Add(descriptor.DisplayName, StringComparer.Ordinal);
|
|
||||||
|
|
||||||
return hashCodeCombiner.CombinedHash;
|
return hash.CombinedHash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
|
|
||||||
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
public virtual bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||||
{
|
{
|
||||||
if (descriptorX == descriptorY)
|
if (object.ReferenceEquals(descriptorX, descriptorY))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +62,7 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
return descriptorX != null &&
|
return descriptorX != null &&
|
||||||
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.Kind, descriptorY.Kind, StringComparison.Ordinal) &&
|
||||||
string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal) &&
|
string.Equals(descriptorX.AssemblyName, descriptorY.AssemblyName, StringComparison.Ordinal) &&
|
||||||
|
string.Equals(descriptorX.Name, descriptorY.Name, StringComparison.Ordinal) &&
|
||||||
Enumerable.SequenceEqual(
|
Enumerable.SequenceEqual(
|
||||||
descriptorX.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer),
|
descriptorX.BoundAttributes.OrderBy(attribute => attribute.Name, _stringComparer),
|
||||||
descriptorY.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));
|
throw new ArgumentNullException(nameof(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
var hash = HashCodeCombiner.Start();
|
||||||
hashCodeCombiner.Add(descriptor.Kind);
|
hash.Add(descriptor.Kind, StringComparer.Ordinal);
|
||||||
hashCodeCombiner.Add(descriptor.AssemblyName, StringComparer.Ordinal);
|
hash.Add(descriptor.AssemblyName, StringComparer.Ordinal);
|
||||||
|
hash.Add(descriptor.Name, StringComparer.Ordinal);
|
||||||
|
|
||||||
var childTags = descriptor.AllowedChildTags.OrderBy(childTag => childTag.Name, _stringComparer);
|
return hash.CombinedHash;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -54,12 +54,11 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ruleX != null &&
|
return
|
||||||
string.Equals(ruleX.TagName, ruleY.TagName, _stringComparison) &&
|
string.Equals(ruleX.TagName, ruleY.TagName, _stringComparison) &&
|
||||||
string.Equals(ruleX.ParentTag, ruleY.ParentTag, _stringComparison) &&
|
string.Equals(ruleX.ParentTag, ruleY.ParentTag, _stringComparison) &&
|
||||||
ruleX.TagStructure == ruleY.TagStructure &&
|
ruleX.TagStructure == ruleY.TagStructure &&
|
||||||
Enumerable.SequenceEqual(ruleX.Attributes, ruleY.Attributes, _requiredAttributeComparer) &&
|
Enumerable.SequenceEqual(ruleX.Attributes, ruleY.Attributes, _requiredAttributeComparer);
|
||||||
Enumerable.SequenceEqual(ruleX.Diagnostics, ruleY.Diagnostics);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual int GetHashCode(TagMatchingRuleDescriptor rule)
|
public virtual int GetHashCode(TagMatchingRuleDescriptor rule)
|
||||||
|
|
@ -69,18 +68,10 @@ namespace Microsoft.AspNetCore.Razor.Language
|
||||||
throw new ArgumentNullException(nameof(rule));
|
throw new ArgumentNullException(nameof(rule));
|
||||||
}
|
}
|
||||||
|
|
||||||
var hashCodeCombiner = HashCodeCombiner.Start();
|
var hash = HashCodeCombiner.Start();
|
||||||
hashCodeCombiner.Add(rule.TagName, _stringComparer);
|
hash.Add(rule.TagName, _stringComparer);
|
||||||
hashCodeCombiner.Add(rule.ParentTag, _stringComparer);
|
|
||||||
hashCodeCombiner.Add(rule.TagStructure);
|
|
||||||
|
|
||||||
var attributes = rule.Attributes.OrderBy(attribute => attribute.Name, _stringComparer);
|
return hash.CombinedHash;
|
||||||
foreach (var attribute in attributes)
|
|
||||||
{
|
|
||||||
hashCodeCombiner.Add(_requiredAttributeComparer.GetHashCode(attribute));
|
|
||||||
}
|
|
||||||
|
|
||||||
return hashCodeCombiner.CombinedHash;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,18 +29,16 @@ namespace Microsoft.VisualStudio.Editor.Razor
|
||||||
_tagHelperFactsService = tagHelperFactsService;
|
_tagHelperFactsService = tagHelperFactsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// This API attempts to understand a users context as they're typing in a Razor file to provide TagHelper based attribute IntelliSense.
|
||||||
* 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:
|
||||||
* Scenarios for TagHelper attribute IntelliSense follows:
|
// 1. TagHelperDescriptor's have matching required attribute names
|
||||||
* 1. TagHelperDescriptor's have matching required attribute names
|
// -> Provide IntelliSense for the required attributes of those descriptors to lead users towards a TagHelperified element.
|
||||||
* -> 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.
|
||||||
* 2. TagHelperDescriptor entirely applies to current element. Tag name, attributes, everything is fulfilled.
|
// -> Provide IntelliSense for the bound attributes for the applied descriptors.
|
||||||
* -> 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
|
||||||
* 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.
|
||||||
* BoundAttributeDescriptor. By doing this a user can see what C# type a TagHelper expects for the attribute.
|
|
||||||
*/
|
|
||||||
public override AttributeCompletionResult GetAttributeCompletions(AttributeCompletionContext completionContext)
|
public override AttributeCompletionResult GetAttributeCompletions(AttributeCompletionContext completionContext)
|
||||||
{
|
{
|
||||||
if (completionContext == null)
|
if (completionContext == null)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue