提交 28d95173 编写于 作者: C Cyrus Najmabadi

Tweak

上级 9f94fadc
......@@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CodeFixes.AddExplicitCast;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.LanguageServices;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Operations;
......@@ -47,6 +48,7 @@ public CSharpAddExplicitCastCodeFixProvider()
_attributeArgumentFixer = new AttributeArgumentFixer(this);
}
protected override ISyntaxFacts SyntaxFacts => CSharpSyntaxFacts.Instance;
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CS0266, CS1503);
protected override string GetSubItemName(CodeFixContext context, SemanticModel semanticModel,
......@@ -74,7 +76,6 @@ out ImmutableArray<(ExpressionSyntax, ITypeSymbol)> potentialConversionTypes)
{
potentialConversionTypes = ImmutableArray<(ExpressionSyntax, ITypeSymbol)>.Empty;
using var _ = ArrayBuilder<(ExpressionSyntax, ITypeSymbol)>.GetInstance(out var mutablePotentialConversionTypes);
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
if (diagnosticId == CS0266)
{
......@@ -93,7 +94,7 @@ out ImmutableArray<(ExpressionSyntax, ITypeSymbol)> potentialConversionTypes)
{
// invocationNode could be Invocation Expression, Object Creation, Base Constructor...)
mutablePotentialConversionTypes.AddRange(_argumentFixer.GetPotentialConversionTypes(
syntaxFacts, semanticModel, root, targetArgument, argumentList, invocationNode, cancellationToken));
semanticModel, root, targetArgument, argumentList, invocationNode, cancellationToken));
}
else if (spanNode.GetAncestorOrThis<AttributeArgumentSyntax>() is AttributeArgumentSyntax targetAttributeArgument
&& targetAttributeArgument.Parent is AttributeArgumentListSyntax attributeArgumentList
......@@ -101,13 +102,12 @@ out ImmutableArray<(ExpressionSyntax, ITypeSymbol)> potentialConversionTypes)
{
// attribute node
mutablePotentialConversionTypes.AddRange(_attributeArgumentFixer.GetPotentialConversionTypes(
syntaxFacts, semanticModel, root, targetAttributeArgument, attributeArgumentList, attributeNode, cancellationToken));
semanticModel, root, targetAttributeArgument, attributeArgumentList, attributeNode, cancellationToken));
}
}
// clear up duplicate types
potentialConversionTypes = FilterValidPotentialConversionTypes(syntaxFacts, semanticModel,
mutablePotentialConversionTypes);
potentialConversionTypes = FilterValidPotentialConversionTypes(semanticModel, mutablePotentialConversionTypes);
return !potentialConversionTypes.IsEmpty;
}
......
......@@ -4,11 +4,11 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.AddExplicitCast
{
......@@ -23,7 +23,7 @@ public ArgumentFixer(CSharpAddExplicitCastCodeFixProvider provider) : base(provi
protected override ArgumentSyntax GenerateNewArgument(ArgumentSyntax oldArgument, ITypeSymbol conversionType)
=> oldArgument.WithExpression(oldArgument.Expression.Cast(conversionType));
protected override ArgumentListSyntax GenerateNewArgumentList(ArgumentListSyntax oldArgumentList, List<ArgumentSyntax> newArguments)
protected override ArgumentListSyntax GenerateNewArgumentList(ArgumentListSyntax oldArgumentList, ArrayBuilder<ArgumentSyntax> newArguments)
=> oldArgumentList.WithArguments(SyntaxFactory.SeparatedList(newArguments));
protected override SeparatedSyntaxList<ArgumentSyntax> GetArgumentsOfArgumentList(ArgumentListSyntax argumentList)
......
......@@ -4,11 +4,11 @@
#nullable enable
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Extensions;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis.CSharp.CodeFixes.AddExplicitCast
{
......@@ -23,7 +23,7 @@ public AttributeArgumentFixer(CSharpAddExplicitCastCodeFixProvider provider) : b
protected override AttributeArgumentSyntax GenerateNewArgument(AttributeArgumentSyntax oldArgument, ITypeSymbol conversionType)
=> oldArgument.WithExpression(oldArgument.Expression.Cast(conversionType));
protected override AttributeArgumentListSyntax GenerateNewArgumentList(AttributeArgumentListSyntax oldArgumentList, List<AttributeArgumentSyntax> newArguments)
protected override AttributeArgumentListSyntax GenerateNewArgumentList(AttributeArgumentListSyntax oldArgumentList, ArrayBuilder<AttributeArgumentSyntax> newArguments)
=> oldArgumentList.WithArguments(SyntaxFactory.SeparatedList(newArguments));
protected override SeparatedSyntaxList<AttributeArgumentSyntax> GetArgumentsOfArgumentList(AttributeArgumentListSyntax argumentList)
......
......@@ -5,9 +5,7 @@
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
......@@ -34,6 +32,8 @@ internal abstract partial class AbstractAddExplicitCastCodeFixProvider<TExpressi
internal sealed override CodeFixCategory CodeFixCategory => CodeFixCategory.Compile;
protected abstract ISyntaxFacts SyntaxFacts { get; }
/// <summary>
/// Given targetNode and conversionType, generate sub item name like "Cast to 'conversionType'"
/// </summary>
......@@ -43,7 +43,6 @@ internal abstract partial class AbstractAddExplicitCastCodeFixProvider<TExpressi
protected abstract SyntaxNode ApplyFix(SyntaxNode currentRoot, TExpressionSyntax targetNode, ITypeSymbol conversionType);
protected abstract CommonConversion ClassifyConversion(SemanticModel semanticModel, TExpressionSyntax expression, ITypeSymbol type);
// protected abstract SymbolInfo GetSpeculativeAttributeSymbolInfo(SemanticModel semanticModel, int position, TAttributeSyntax attribute);
/// <summary>
/// Output the current type information of the target node and the conversion type(s) that the target node is
......@@ -62,7 +61,8 @@ internal abstract partial class AbstractAddExplicitCastCodeFixProvider<TExpressi
/// True, if there is at least one potential conversion pair, and they are assigned to "potentialConversionTypes"
/// False, if there is no potential conversion pair.
/// </returns>
protected abstract bool TryGetTargetTypeInfo(Document document, SemanticModel semanticModel, SyntaxNode root,
protected abstract bool TryGetTargetTypeInfo(
Document document, SemanticModel semanticModel, SyntaxNode root,
string diagnosticId, TExpressionSyntax spanNode, CancellationToken cancellationToken,
out ImmutableArray<(TExpressionSyntax node, ITypeSymbol type)> potentialConversionTypes);
......@@ -129,7 +129,7 @@ private static void ReportTelemetryIfNecessary(ImmutableArray<(TExpressionSyntax
}
protected ImmutableArray<(TExpressionSyntax, ITypeSymbol)> FilterValidPotentialConversionTypes(
ISyntaxFactsService syntaxFacts, SemanticModel semanticModel,
SemanticModel semanticModel,
ArrayBuilder<(TExpressionSyntax node, ITypeSymbol type)> mutablePotentialConversionTypes)
{
using var _ = ArrayBuilder<(TExpressionSyntax, ITypeSymbol)>.GetInstance(out var validPotentialConversionTypes);
......@@ -141,7 +141,7 @@ private static void ReportTelemetryIfNecessary(ImmutableArray<(TExpressionSyntax
// For cases like object creation expression. for example:
// Derived d = [||]new Base();
// It is always invalid except the target node has explicit conversion operator or is numeric.
if (syntaxFacts.IsObjectCreationExpression(targetNode)
if (SyntaxFacts.IsObjectCreationExpression(targetNode)
&& !ClassifyConversion(semanticModel, targetNode, targetNodeConversionType).IsUserDefined)
{
continue;
......
......@@ -9,7 +9,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -42,7 +41,6 @@ protected Fixer(AbstractAddExplicitCastCodeFixProvider<TExpressionSyntax> provid
/// Return all the available cast pairs, format is (target argument expression, potential conversion type)
/// </returns>
public ImmutableArray<(TExpressionSyntax, ITypeSymbol)> GetPotentialConversionTypes(
ISyntaxFactsService syntaxFacts,
SemanticModel semanticModel,
SyntaxNode root,
TArgumentSyntax targetArgument,
......@@ -66,10 +64,10 @@ protected Fixer(AbstractAddExplicitCastCodeFixProvider<TExpressionSyntax> provid
using var __ = ArrayBuilder<(TExpressionSyntax, ITypeSymbol)>.GetInstance(out var mutablePotentialConversionTypes);
foreach (var candidateSymbol in candidateSymbols.OfType<IMethodSymbol>())
{
if (CanArgumentTypesBeConvertedToParameterTypes(syntaxFacts,
semanticModel, root, argumentList, candidateSymbol.Parameters, targetArgument,
cancellationToken, out var targetArgumentConversionType)
&& syntaxFacts.GetExpressionOfArgument(targetArgument) is TExpressionSyntax argumentExpression)
if (CanArgumentTypesBeConvertedToParameterTypes(
semanticModel, root, argumentList, candidateSymbol.Parameters,
targetArgument, cancellationToken, out var targetArgumentConversionType)
&& _provider.SyntaxFacts.GetExpressionOfArgument(targetArgument) is TExpressionSyntax argumentExpression)
{
mutablePotentialConversionTypes.Add((argumentExpression, targetArgumentConversionType));
}
......@@ -112,7 +110,6 @@ protected Fixer(AbstractAddExplicitCastCodeFixProvider<TExpressionSyntax> provid
/// False, otherwise.
/// </returns>
public bool CanArgumentTypesBeConvertedToParameterTypes(
ISyntaxFactsService syntaxFacts,
SemanticModel semanticModel,
SyntaxNode root,
TArgumentListSyntax argumentList,
......@@ -127,6 +124,8 @@ protected Fixer(AbstractAddExplicitCastCodeFixProvider<TExpressionSyntax> provid
if (parameters.Length == 0)
return false;
var syntaxFacts = _provider.SyntaxFacts;
var arguments = GetArgumentsOfArgumentList(argumentList);
using var _ = ArrayBuilder<TArgumentSyntax>.GetInstance(out var newArguments);
......
......@@ -2,6 +2,7 @@
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
......@@ -24,7 +25,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
End Select
End Function
Protected Overrides Function GenerateNewArgumentList(oldArgumentList As ArgumentListSyntax, newArguments As List(Of ArgumentSyntax)) As ArgumentListSyntax
Protected Overrides Function GenerateNewArgumentList(oldArgumentList As ArgumentListSyntax, newArguments As ArrayBuilder(Of ArgumentSyntax)) As ArgumentListSyntax
Return oldArgumentList.WithArguments(SyntaxFactory.SeparatedList(newArguments))
End Function
......
......@@ -13,6 +13,7 @@ Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.Operations
Imports Microsoft.CodeAnalysis.PooledObjects
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic.LanguageServices
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
......@@ -34,7 +35,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
_fixer = New ArgumentFixer(Me)
End Sub
Protected Overrides ReadOnly Property SyntaxFacts As ISyntaxFacts = VisualBasicSyntaxFacts.Instance
Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC30512, BC42016, BC30518, BC30519)
Protected Overrides Function GetSubItemName(context As CodeFixContext, semanticModel As SemanticModel,
targetNode As SyntaxNode, conversionType As ITypeSymbol) As String
Return String.Format(
......@@ -59,7 +63,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
ByRef potentialConversionTypes As ImmutableArray(Of (ExpressionSyntax, ITypeSymbol))) As Boolean
potentialConversionTypes = ImmutableArray(Of (ExpressionSyntax, ITypeSymbol)).Empty
Dim mutablePotentialConversionTypes = ArrayBuilder(Of (ExpressionSyntax, ITypeSymbol)).GetInstance()
Dim syntaxFacts = document.GetRequiredLanguageService(Of ISyntaxFactsService)
Select Case diagnosticId
Case BC30512, BC42016
......@@ -69,8 +72,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
Dim argumentList = DirectCast(argument.Parent, ArgumentListSyntax)
Dim invocationNode = argumentList.Parent
mutablePotentialConversionTypes.AddRange(_fixer.GetPotentialConversionTypes(syntaxFacts, semanticModel,
root, argument, argumentList, invocationNode, cancellationToken))
mutablePotentialConversionTypes.AddRange(_fixer.GetPotentialConversionTypes(
semanticModel, root, argument, argumentList, invocationNode, cancellationToken))
Else
' spanNode is a right expression in assignment operation
Dim inferenceService = document.GetRequiredLanguageService(Of ITypeInferenceService)()
......@@ -83,13 +86,12 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
Function(node) Not node.ChildNodes.OfType(Of ArgumentListSyntax).IsEmpty())
' Collect available cast pairs without target argument
mutablePotentialConversionTypes.AddRange(GetPotentialConversionTypesWithInvocationNode(syntaxFacts,
semanticModel, root, invocationNode, cancellationToken))
mutablePotentialConversionTypes.AddRange(
GetPotentialConversionTypesWithInvocationNode(semanticModel, root, invocationNode, cancellationToken))
End Select
' clear up duplicate types
potentialConversionTypes = FilterValidPotentialConversionTypes(syntaxFacts, semanticModel,
mutablePotentialConversionTypes)
potentialConversionTypes = FilterValidPotentialConversionTypes(semanticModel, mutablePotentialConversionTypes)
Return Not potentialConversionTypes.IsEmpty
End Function
......@@ -98,11 +100,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
Return semanticModel.ClassifyConversion(expression, type).ToCommonConversion()
End Function
'Protected Overrides Function GetSpeculativeAttributeSymbolInfo(semanticModel As SemanticModel,
' position As Integer, attribute As AttributeSyntax) As SymbolInfo
' Return semanticModel.GetSpeculativeSymbolInfo(position, attribute)
'End Function
''' <summary>
''' Find the first argument that need to be cast
''' </summary>
......@@ -111,7 +108,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
''' <returns>
''' Return the first argument that need to be cast, could be null if such argument doesn't exist
''' </returns>
Private Function GetTargetArgument(syntaxFacts As ISyntaxFactsService, semanticModel As SemanticModel,
Private Function GetTargetArgument(semanticModel As SemanticModel,
parameters As ImmutableArray(Of IParameterSymbol), arguments As SeparatedSyntaxList(Of ArgumentSyntax)) As ArgumentSyntax
If parameters.Length = 0 Then
Return Nothing
......@@ -123,7 +120,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
Dim parameterIndex = Math.Min(i, parameters.Length - 1)
' If the argument has a name, get the corresponding parameter index
Dim argumentName = syntaxFacts.GetNameForArgument(arguments(i))
Dim argumentName = SyntaxFacts.GetNameForArgument(arguments(i))
If argumentName IsNot String.Empty AndAlso Not FindCorrespondingParameterByName(argumentName, parameters,
parameterIndex) Then
Return Nothing
......@@ -162,7 +159,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
''' <returns>
''' Return all the available cast pairs, format is (argument expression, potential conversion type)
''' </returns>
Private Function GetPotentialConversionTypesWithInvocationNode(syntaxFacts As ISyntaxFactsService,
Private Function GetPotentialConversionTypesWithInvocationNode(
semanticModel As SemanticModel, root As SyntaxNode, invocationNode As SyntaxNode,
cancellationToken As CancellationToken) As ImmutableArray(Of (ExpressionSyntax, ITypeSymbol))
Dim argumentList = invocationNode.ChildNodes.OfType(Of ArgumentListSyntax).FirstOrDefault()
......@@ -173,15 +170,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.AddExplicitCast
Dim mutablePotentialConversionTypes = ArrayBuilder(Of (ExpressionSyntax, ITypeSymbol)).GetInstance()
For Each candidateSymbol In candidateSymbols.OfType(Of IMethodSymbol)()
Dim targetArgument = GetTargetArgument(syntaxFacts, semanticModel, candidateSymbol.Parameters, argumentList.Arguments)
Dim targetArgument = GetTargetArgument(semanticModel, candidateSymbol.Parameters, argumentList.Arguments)
If targetArgument Is Nothing Then
Continue For
End If
Dim conversionType As ITypeSymbol = Nothing
If _fixer.CanArgumentTypesBeConvertedToParameterTypes(
syntaxFacts, semanticModel, root, argumentList,
candidateSymbol.Parameters, targetArgument, cancellationToken, conversionType) Then
semanticModel, root, argumentList, candidateSymbol.Parameters, targetArgument, cancellationToken, conversionType) Then
mutablePotentialConversionTypes.Add((targetArgument.GetExpression(), conversionType))
End If
Next
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册