Thanks to visit codestin.com
Credit goes to github.com

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
Expand Up @@ -2,16 +2,30 @@

using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Analyzer.Utilities.Lightup;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.NetCore.Analyzers.Runtime;

namespace Microsoft.NetCore.CSharp.Analyzers.Runtime
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class CSharpDetectPreviewFeatureAnalyzer : DetectPreviewFeatureAnalyzer
{
protected override ISymbol? SymbolFromAwaitOperation(IAwaitOperation operation)
{
if (operation.Syntax is not AwaitExpressionSyntax awaitSyntax)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider testing with await using and await foreach

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are going to need new public APIs. I'll open a followup.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
return null;
}

var awaitableInfo = operation.SemanticModel.GetAwaitExpressionInfo(awaitSyntax);
return awaitableInfo.RuntimeAwaitMethod;
}

protected override SyntaxNode? GetPreviewSyntaxNodeForFieldsOrEvents(ISymbol fieldOrEventSymbol, ISymbol previewSymbol)
{
ImmutableArray<SyntaxReference> fieldOrEventReferences = fieldOrEventSymbol.DeclaringSyntaxReferences;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ public override void Initialize(AnalysisContext context)
OperationKind.ArrayCreation,
OperationKind.CatchClause,
OperationKind.TypeOf,
OperationKind.EventAssignment
OperationKind.EventAssignment,
OperationKind.Await
);

// Handle preview symbol definitions
Expand Down Expand Up @@ -809,7 +810,7 @@ private bool OperationUsesPreviewFeatures(OperationAnalysisContext context,
return false;
}

private static ISymbol? GetOperationSymbol(IOperation operation)
private ISymbol? GetOperationSymbol(IOperation operation)
=> operation switch
{
IInvocationOperation iOperation => iOperation.TargetMethod,
Expand All @@ -824,6 +825,7 @@ private bool OperationUsesPreviewFeatures(OperationAnalysisContext context,
ICatchClauseOperation catchClauseOperation => catchClauseOperation.ExceptionType,
ITypeOfOperation typeOfOperation => typeOfOperation.TypeOperand,
IEventAssignmentOperation eventAssignment => GetOperationSymbol(eventAssignment.EventReference),
IAwaitOperation awaitOperation => SymbolFromAwaitOperation(awaitOperation),
_ => null,
};

Expand All @@ -838,6 +840,8 @@ private bool OperationUsesPreviewFeatures(OperationAnalysisContext context,
return ret;
}

protected abstract ISymbol? SymbolFromAwaitOperation(IAwaitOperation operation);

private bool TypeParametersHavePreviewAttribute(ISymbol namedTypeSymbolOrMethodSymbol,
ImmutableArray<ITypeParameterSymbol> typeParameters,
ConcurrentDictionary<ISymbol, (bool isPreview, string? message, string? url)> requiresPreviewFeaturesSymbols,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Diagnostics
Imports Microsoft.CodeAnalysis.Operations
Imports Microsoft.NetCore.Analyzers.Runtime
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax

Expand All @@ -16,6 +17,10 @@ Namespace Microsoft.NetCore.VisualBasic.Analyzers.Runtime
Return identifier.ValueText.Equals(previewInterfaceSymbol.Name, StringComparison.OrdinalIgnoreCase)
End Function

Protected Overrides Function SymbolFromAwaitOperation(operation As IAwaitOperation) As ISymbol
Return Nothing
End Function

Private Shared Function GetElementTypeForNullableAndArrayTypeNodes(parameterType As TypeSyntax) As TypeSyntax
Dim ret As TypeSyntax = parameterType
Dim loopVariable = TryCast(parameterType, NullableTypeSyntax)
Expand Down Expand Up @@ -334,4 +339,4 @@ Namespace Microsoft.NetCore.VisualBasic.Analyzers.Runtime
End Function
End Class

End Namespace
End Namespace
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxGeneratorExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\SyntaxNodeExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Lightup\AwaitExpressionInfoWrapper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Lightup\SyntaxKindEx.cs" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;

namespace Analyzer.Utilities.Lightup
{
internal static class AwaitExpressionInfoWrapper
{
private static Func<AwaitExpressionInfo, IMethodSymbol?>? s_RuntimeAwaitMethodAccessor;

extension(AwaitExpressionInfo info)
{
public IMethodSymbol? RuntimeAwaitMethod
{
get
{
LazyInitializer.EnsureInitialized(ref s_RuntimeAwaitMethodAccessor, () =>
{
return LightupHelpers.CreatePropertyAccessor<AwaitExpressionInfo, IMethodSymbol?>(
typeof(AwaitExpressionInfo),
"info",
"RuntimeAwaitMethod",
fallbackResult: null);
});

RoslynDebug.Assert(s_RuntimeAwaitMethodAccessor is not null);
return s_RuntimeAwaitMethodAccessor(info);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ internal static Func<TSymbol, TProperty> CreateSymbolPropertyAccessor<TSymbol, T
where TSymbol : ISymbol
=> CreatePropertyAccessor<TSymbol, TProperty>(type, "symbol", propertyName, fallbackResult);

private static Func<T, TProperty> CreatePropertyAccessor<T, TProperty>(Type? type, string parameterName, string propertyName, TProperty fallbackResult)
internal static Func<T, TProperty> CreatePropertyAccessor<T, TProperty>(Type? type, string parameterName, string propertyName, TProperty fallbackResult)
{
if (!TryGetProperty<T, TProperty>(type, propertyName, out var property))
{
Expand Down
Loading
Loading