Skip to content

Commit

Permalink
Store WellKnownTypeProvider (from dotnet/roslyn-analyzers) in TagHelp…
Browse files Browse the repository at this point in the history
…erDescriptorProviderContext
  • Loading branch information
sharwell committed Feb 22, 2023
1 parent df8e6ae commit 6e78f5a
Show file tree
Hide file tree
Showing 23 changed files with 477 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class StringParameterViewComponent
var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
context.SetTypeProvider(new WellKnownTypeProvider(compilation));

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class StringParameterViewComponent
var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
context.SetTypeProvider(new WellKnownTypeProvider(compilation));

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class StringParameterViewComponent
var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
context.SetTypeProvider(new WellKnownTypeProvider(compilation));

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#nullable disable

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
Expand All @@ -23,7 +24,7 @@ public IReadOnlyList<TagHelperDescriptor> GetDescriptors()
var compilation = CSharpCompilation.Create("__TagHelpers", references: _referenceFeature.References);
if (IsValidCompilation(compilation))
{
context.SetCompilation(compilation);
context.SetTypeProvider(new WellKnownTypeProvider(compilation));
}

for (var i = 0; i < _providers.Length; i++)
Expand All @@ -40,7 +41,7 @@ protected override void OnInitialized()
_providers = Engine.Features.OfType<ITagHelperDescriptorProvider>().OrderBy(f => f.Order).ToArray();
}

internal static bool IsValidCompilation(Compilation compilation)
internal static bool IsValidCompilation([NotNullWhen(true)] Compilation compilation)
{
var @string = compilation.GetSpecialType(SpecialType.System_String);

Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#nullable enable
*REMOVED*~static Microsoft.CodeAnalysis.Razor.TagHelperDescriptorProviderContextExtensions.SetCompilation(this Microsoft.AspNetCore.Razor.Language.TagHelperDescriptorProviderContext context, Microsoft.CodeAnalysis.Compilation compilation) -> void
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
Expand All @@ -16,4 +16,51 @@ internal static bool HasFullName(this ISymbol symbol, string fullName)
{
return symbol.ToDisplayString(FullNameTypeDisplayFormat).Equals(fullName, StringComparison.Ordinal);
}

internal static SymbolVisibility GetResultantVisibility(this ISymbol symbol)
{
// Start by assuming it's visible.
SymbolVisibility visibility = SymbolVisibility.Public;

switch (symbol.Kind)
{
case SymbolKind.Alias:
// Aliases are uber private. They're only visible in the same file that they
// were declared in.
return SymbolVisibility.Private;

case SymbolKind.Parameter:
// Parameters are only as visible as their containing symbol
return GetResultantVisibility(symbol.ContainingSymbol);

case SymbolKind.TypeParameter:
// Type Parameters are private.
return SymbolVisibility.Private;
}

while (symbol != null && symbol.Kind != SymbolKind.Namespace)
{
switch (symbol.DeclaredAccessibility)
{
// If we see anything private, then the symbol is private.
case Accessibility.NotApplicable:
case Accessibility.Private:
return SymbolVisibility.Private;

// If we see anything internal, then knock it down from public to
// internal.
case Accessibility.Internal:
case Accessibility.ProtectedAndInternal:
visibility = SymbolVisibility.Internal;
break;

// For anything else (Public, Protected, ProtectedOrInternal), the
// symbol stays at the level we've gotten so far.
}

symbol = symbol.ContainingSymbol;
}

return visibility;
}
}
12 changes: 12 additions & 0 deletions src/Compiler/Microsoft.CodeAnalysis.Razor/src/SymbolVisibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// 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;

internal enum SymbolVisibility
{
Public = 0,
Internal = 1,
Private = 2,
Friend = Internal,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;

namespace Microsoft.CodeAnalysis.Razor;

/// <summary>
/// Extensions for <see cref="SymbolVisibility"/>.
/// </summary>
internal static class SymbolVisibilityExtensions
{
/// <summary>
/// Determines whether <paramref name="typeVisibility"/> is at least as visible as <paramref name="comparisonVisibility"/>.
/// </summary>
/// <param name="typeVisibility">The visibility to compare against.</param>
/// <param name="comparisonVisibility">The visibility to compare with.</param>
/// <returns>True if one can say that <paramref name="typeVisibility"/> is at least as visible as <paramref name="comparisonVisibility"/>.</returns>
/// <remarks>
/// For example, <see cref="SymbolVisibility.Public"/> is at least as visible as <see cref="SymbolVisibility.Internal"/>, but <see cref="SymbolVisibility.Private"/> is not as visible as <see cref="SymbolVisibility.Public"/>.
/// </remarks>
public static bool IsAtLeastAsVisibleAs(this SymbolVisibility typeVisibility, SymbolVisibility comparisonVisibility)
{
return typeVisibility switch
{
SymbolVisibility.Public => true,
SymbolVisibility.Internal => comparisonVisibility != SymbolVisibility.Public,
SymbolVisibility.Private => comparisonVisibility == SymbolVisibility.Private,
_ => throw new ArgumentOutOfRangeException(nameof(typeVisibility), typeVisibility, null),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,24 @@ public static Compilation GetCompilation(this TagHelperDescriptorProviderContext
return (Compilation)context.Items[typeof(Compilation)];
}

public static void SetCompilation(this TagHelperDescriptorProviderContext context, Compilation compilation)
public static WellKnownTypeProvider GetTypeProvider(this TagHelperDescriptorProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

context.Items[typeof(Compilation)] = compilation;
return (WellKnownTypeProvider)context.Items[typeof(WellKnownTypeProvider)];
}

public static void SetTypeProvider(this TagHelperDescriptorProviderContext context, WellKnownTypeProvider typeProvider)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

context.Items[typeof(Compilation)] = typeProvider.Compilation;
context.Items[typeof(WellKnownTypeProvider)] = typeProvider;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// 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;

internal static class WellKnownTypeNames
{
public const string SystemThreadingTasksTask1 = "System.Threading.Tasks.Task`1";
}
Loading

0 comments on commit 6e78f5a

Please sign in to comment.