Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.AspNetCore.Mvc.Razor.Extensions;

namespace Microsoft.CodeAnalysis.Razor.Compiler.Language.Extensions;

internal static partial class INamedTypeSymbolExtensions
{
private sealed partial class Cache
{
private sealed class IsViewComponentResult
{
public bool IsViewComponent { get; }
public INamedTypeSymbol ViewComponentAttribute { get; }
public INamedTypeSymbol? NonViewComponentAttribute { get; }

public IsViewComponentResult(INamedTypeSymbol symbol, INamedTypeSymbol viewComponentAttribute, INamedTypeSymbol? nonViewComponentAttribute)
{
ViewComponentAttribute = viewComponentAttribute;
NonViewComponentAttribute = nonViewComponentAttribute;

if (symbol.DeclaredAccessibility != Accessibility.Public ||
symbol.IsAbstract ||
symbol.IsGenericType ||
AttributeIsDefined(symbol, nonViewComponentAttribute))
{
IsViewComponent = false;
}
else
{
IsViewComponent = symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.Ordinal) ||
AttributeIsDefined(symbol, viewComponentAttribute);
}
}

public bool IsMatchingCache(INamedTypeSymbol viewComponentAttribute, INamedTypeSymbol? nonViewComponentAttribute)
{
return SymbolEqualityComparer.Default.Equals(ViewComponentAttribute, viewComponentAttribute)
&& SymbolEqualityComparer.Default.Equals(NonViewComponentAttribute, nonViewComponentAttribute);
}

private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol? queryAttribute)
{
if (queryAttribute == null)
{
return false;
}

var currentType = type;
while (currentType != null)
{
foreach (var attribute in currentType.GetAttributes())
{
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, queryAttribute))
{
return true;
}
}

currentType = currentType.BaseType;
}

return false;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.CodeAnalysis.Razor.Compiler.Language.Extensions;

internal static partial class INamedTypeSymbolExtensions
{
private sealed partial class Cache(INamedTypeSymbol symbol)
{
private readonly INamedTypeSymbol _symbol = symbol;
private IsViewComponentResult? _isViewComponentResult;

public bool IsViewComponent(INamedTypeSymbol viewComponentAttribute, INamedTypeSymbol? nonViewComponentAttribute)
{
var isViewComponentResult = _isViewComponentResult;
if (isViewComponentResult is null
|| !isViewComponentResult.IsMatchingCache(viewComponentAttribute, nonViewComponentAttribute))
{
isViewComponentResult = new IsViewComponentResult(_symbol, viewComponentAttribute, nonViewComponentAttribute);
_isViewComponentResult = isViewComponentResult;
}

return isViewComponentResult.IsViewComponent;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.Runtime.CompilerServices;

namespace Microsoft.CodeAnalysis.Razor.Compiler.Language.Extensions;

internal static partial class INamedTypeSymbolExtensions
{
private static readonly ConditionalWeakTable<INamedTypeSymbol, Cache> s_instance = new();

public static bool IsViewComponent(this INamedTypeSymbol symbol, INamedTypeSymbol viewComponentAttribute, INamedTypeSymbol? nonViewComponentAttribute)
{
var cache = s_instance.GetValue(symbol, static s => new Cache(s));

return cache.IsViewComponent(viewComponentAttribute, nonViewComponentAttribute);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Razor.Compiler.Language.Extensions;

namespace Microsoft.AspNetCore.Mvc.Razor.Extensions;

Expand Down Expand Up @@ -61,33 +63,6 @@ internal bool IsViewComponent(INamedTypeSymbol symbol)
return false;
}

if (symbol.DeclaredAccessibility != Accessibility.Public ||
symbol.IsAbstract ||
symbol.IsGenericType ||
AttributeIsDefined(symbol, _nonViewComponentAttribute))
{
return false;
}

return symbol.Name.EndsWith(ViewComponentTypes.ViewComponentSuffix, StringComparison.Ordinal) ||
AttributeIsDefined(symbol, _viewComponentAttribute);
}

private static bool AttributeIsDefined(INamedTypeSymbol? type, INamedTypeSymbol? queryAttribute)
{
if (type == null || queryAttribute == null)
{
return false;
}

foreach (var attribute in type.GetAttributes())
{
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, queryAttribute))
{
return true;
}
}

return AttributeIsDefined(type.BaseType, queryAttribute);
return symbol.IsViewComponent(_viewComponentAttribute, _nonViewComponentAttribute);
}
}