未验证 提交 9c0370c3 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Merge pull request #41416 from CyrusNajmabadi/publicMethods

Expose several SyntaxGenerator methods.
......@@ -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.
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Test.Utilities;
using Xunit;
......@@ -318,6 +319,34 @@ public void TestConditionalExpression1()
vbSimple: "If(E, T, F)");
}
[Fact]
public void TestConditionalAccessExpression1()
{
Test(
f => f.ConditionalAccessExpression(
f.IdentifierName("E"),
f.MemberBindingExpression(
f.IdentifierName("T"))),
cs: "E?.T",
csSimple: "E?.T",
vb: "E?.T",
vbSimple: "E?.T");
}
[Fact]
public void TestConditionalAccessExpression2()
{
Test(
f => f.ConditionalAccessExpression(
f.IdentifierName("E"),
f.ElementBindingExpression(
f.Argument(f.IdentifierName("T")))),
cs: "E?[T]",
csSimple: "E?[T]",
vb: "E?(T)",
vbSimple: "E?(T)");
}
[Fact]
public void TestInvocation1()
{
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Composition;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
......@@ -18,11 +20,16 @@ internal class CSharpUseNullPropagationCodeFixProvider : AbstractUseNullPropagat
InvocationExpressionSyntax,
MemberAccessExpressionSyntax,
ConditionalAccessExpressionSyntax,
ElementAccessExpressionSyntax>
ElementAccessExpressionSyntax,
ElementBindingExpressionSyntax,
BracketedArgumentListSyntax>
{
[ImportingConstructor]
public CSharpUseNullPropagationCodeFixProvider()
{
}
protected override ElementBindingExpressionSyntax ElementBindingExpression(BracketedArgumentListSyntax argumentList)
=> SyntaxFactory.ElementBindingExpression(argumentList);
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Linq;
......@@ -25,7 +27,9 @@ internal abstract class AbstractUseNullPropagationCodeFixProvider<
TInvocationExpression,
TMemberAccessExpression,
TConditionalAccessExpression,
TElementAccessExpression> : SyntaxEditorBasedCodeFixProvider
TElementAccessExpression,
TElementBindingExpression,
TElementBindingArgumentList> : SyntaxEditorBasedCodeFixProvider
where TSyntaxKind : struct
where TExpressionSyntax : SyntaxNode
where TConditionalExpressionSyntax : TExpressionSyntax
......@@ -34,7 +38,11 @@ internal abstract class AbstractUseNullPropagationCodeFixProvider<
where TMemberAccessExpression : TExpressionSyntax
where TConditionalAccessExpression : TExpressionSyntax
where TElementAccessExpression : TExpressionSyntax
where TElementBindingExpression : TExpressionSyntax
where TElementBindingArgumentList : SyntaxNode
{
protected abstract TElementBindingExpression ElementBindingExpression(TElementBindingArgumentList argumentList);
public override ImmutableArray<string> FixableDiagnosticIds
=> ImmutableArray.Create(IDEDiagnosticIds.UseNullPropagationDiagnosticId);
......@@ -55,8 +63,8 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
Document document, ImmutableArray<Diagnostic> diagnostics,
SyntaxEditor editor, CancellationToken cancellationToken)
{
var syntaxFacts = document.GetLanguageService<ISyntaxFactsService>();
var semanticFacts = document.GetLanguageService<ISemanticFactsService>();
var syntaxFacts = document.GetRequiredLanguageService<ISyntaxFactsService>();
var semanticFacts = document.GetRequiredLanguageService<ISemanticFactsService>();
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var generator = editor.Generator;
var root = editor.OriginalRoot;
......@@ -116,14 +124,14 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
// goo?.Bar() not goo?.Value.Bar();
return CreateConditionalAccessExpression(
syntaxFacts, generator, whenPart, match,
memberAccess.Parent, currentConditional);
memberAccess.Parent!, currentConditional);
}
}
}
return CreateConditionalAccessExpression(
syntaxFacts, generator, whenPart, match,
match.Parent, currentConditional);
match.Parent!, currentConditional);
}
private SyntaxNode CreateConditionalAccessExpression(
......@@ -141,11 +149,10 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
if (matchParent is TElementAccessExpression elementAccess)
{
var argumentList = (TElementBindingArgumentList)syntaxFacts.GetArgumentListOfElementAccessExpression(elementAccess);
return whenPart.ReplaceNode(elementAccess,
generator.ConditionalAccessExpression(
match,
generator.ElementBindingExpression(
syntaxFacts.GetArgumentListOfElementAccessExpression(elementAccess))));
match, ElementBindingExpression(argumentList)));
}
return currentConditional;
......
......@@ -18,10 +18,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UseNullPropagation
InvocationExpressionSyntax,
MemberAccessExpressionSyntax,
ConditionalAccessExpressionSyntax,
InvocationExpressionSyntax)
InvocationExpressionSyntax,
InvocationExpressionSyntax,
ArgumentListSyntax)
<ImportingConstructor>
Public Sub New()
End Sub
Protected Overrides Function ElementBindingExpression(argumentList As ArgumentListSyntax) As InvocationExpressionSyntax
Return SyntaxFactory.InvocationExpression(Nothing, argumentList)
End Function
End Class
End Namespace
......@@ -3293,14 +3293,15 @@ internal override SyntaxNode MemberAccessExpressionWorker(SyntaxNode expression,
(SimpleNameSyntax)simpleName);
}
internal override SyntaxNode ConditionalAccessExpression(SyntaxNode expression, SyntaxNode whenNotNull)
public override SyntaxNode ConditionalAccessExpression(SyntaxNode expression, SyntaxNode whenNotNull)
=> SyntaxFactory.ConditionalAccessExpression((ExpressionSyntax)expression, (ExpressionSyntax)whenNotNull);
internal override SyntaxNode MemberBindingExpression(SyntaxNode name)
public override SyntaxNode MemberBindingExpression(SyntaxNode name)
=> SyntaxFactory.MemberBindingExpression((SimpleNameSyntax)name);
internal override SyntaxNode ElementBindingExpression(SyntaxNode argumentList)
=> SyntaxFactory.ElementBindingExpression((BracketedArgumentListSyntax)argumentList);
public override SyntaxNode ElementBindingExpression(IEnumerable<SyntaxNode> arguments)
=> SyntaxFactory.ElementBindingExpression(
SyntaxFactory.BracketedArgumentList(SyntaxFactory.SeparatedList(arguments)));
/// <summary>
/// Parenthesize the left hand size of a member access, invocation or element access expression
......
......@@ -1978,9 +1978,29 @@ public SyntaxNode TupleElementExpression(ITypeSymbol type, string name = null)
/// </summary>
public abstract SyntaxNode ConditionalExpression(SyntaxNode condition, SyntaxNode whenTrue, SyntaxNode whenFalse);
internal abstract SyntaxNode ConditionalAccessExpression(SyntaxNode expression, SyntaxNode whenNotNull);
internal abstract SyntaxNode MemberBindingExpression(SyntaxNode name);
internal abstract SyntaxNode ElementBindingExpression(SyntaxNode argumentList);
/// <summary>
/// Creates an expression that denotes a conditional access operation. Use <see
/// cref="MemberBindingExpression"/> and <see
/// cref="ElementBindingExpression(IEnumerable{SyntaxNode})"/> to generate the <paramref
/// name="whenNotNull"/> argument.
/// </summary>
public abstract SyntaxNode ConditionalAccessExpression(SyntaxNode expression, SyntaxNode whenNotNull);
/// <summary>
/// Creates an expression that denotes a member binding operation.
/// </summary>
public abstract SyntaxNode MemberBindingExpression(SyntaxNode name);
/// <summary>
/// Creates an expression that denotes an element binding operation.
/// </summary>
public abstract SyntaxNode ElementBindingExpression(IEnumerable<SyntaxNode> arguments);
/// <summary>
/// Creates an expression that denotes an element binding operation.
/// </summary>
public SyntaxNode ElementBindingExpression(params SyntaxNode[] arguments)
=> ElementBindingExpression((IEnumerable<SyntaxNode>)arguments);
/// <summary>
/// Creates an expression that denotes a coalesce operation.
......
*REMOVED*Microsoft.CodeAnalysis.TextDocument.Project.set -> void
*REMOVED*Microsoft.CodeAnalysis.TextDocument.TextDocument() -> void
Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ElementBindingExpression(params Microsoft.CodeAnalysis.SyntaxNode[] arguments) -> Microsoft.CodeAnalysis.SyntaxNode
Microsoft.CodeAnalysis.Options.DocumentOptionSet.WithChangedOption<T>(Microsoft.CodeAnalysis.Options.PerLanguageOption<T> option, T value) -> Microsoft.CodeAnalysis.Options.DocumentOptionSet
Microsoft.CodeAnalysis.Project.RemoveDocuments(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DocumentId> documentIds) -> Microsoft.CodeAnalysis.Project
Microsoft.CodeAnalysis.Solution.RemoveAdditionalDocuments(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DocumentId> documentIds) -> Microsoft.CodeAnalysis.Solution
Microsoft.CodeAnalysis.Solution.RemoveAnalyzerConfigDocuments(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DocumentId> documentIds) -> Microsoft.CodeAnalysis.Solution
Microsoft.CodeAnalysis.Solution.RemoveDocuments(System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.DocumentId> documentIds) -> Microsoft.CodeAnalysis.Solution
Microsoft.CodeAnalysis.Solution.WithOptions(Microsoft.CodeAnalysis.Options.OptionSet options) -> Microsoft.CodeAnalysis.Solution
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ConditionalAccessExpression(Microsoft.CodeAnalysis.SyntaxNode expression, Microsoft.CodeAnalysis.SyntaxNode whenNotNull) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.ElementBindingExpression(System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.SyntaxNode> arguments) -> Microsoft.CodeAnalysis.SyntaxNode
abstract Microsoft.CodeAnalysis.Editing.SyntaxGenerator.MemberBindingExpression(Microsoft.CodeAnalysis.SyntaxNode name) -> Microsoft.CodeAnalysis.SyntaxNode
static Microsoft.CodeAnalysis.Formatting.Formatter.OrganizeImportsAsync(Microsoft.CodeAnalysis.Document document, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<Microsoft.CodeAnalysis.Document>
static Microsoft.CodeAnalysis.Simplification.Simplifier.AddImportsAnnotation.get -> Microsoft.CodeAnalysis.SyntaxAnnotation
......@@ -289,19 +289,19 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
DirectCast(simpleName, SimpleNameSyntax))
End Function
Friend Overrides Function ConditionalAccessExpression(expression As SyntaxNode, whenNotNull As SyntaxNode) As SyntaxNode
Public Overrides Function ConditionalAccessExpression(expression As SyntaxNode, whenNotNull As SyntaxNode) As SyntaxNode
Return SyntaxFactory.ConditionalAccessExpression(
DirectCast(expression, ExpressionSyntax),
DirectCast(whenNotNull, ExpressionSyntax))
End Function
Friend Overrides Function MemberBindingExpression(name As SyntaxNode) As SyntaxNode
Public Overrides Function MemberBindingExpression(name As SyntaxNode) As SyntaxNode
Return SyntaxFactory.SimpleMemberAccessExpression(DirectCast(name, SimpleNameSyntax))
End Function
Friend Overrides Function ElementBindingExpression(argumentList As SyntaxNode) As SyntaxNode
Public Overrides Function ElementBindingExpression(arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode
Return SyntaxFactory.InvocationExpression(expression:=Nothing,
argumentList:=DirectCast(argumentList, ArgumentListSyntax))
SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(arguments)))
End Function
' parenthesize the left-side of a dot or target of an invocation if not unnecessary
......
......@@ -29,7 +29,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Simplification
Dim rewrittenNode = invocationExpression
If invocationExpression.Expression.Kind = SyntaxKind.SimpleMemberAccessExpression Then
If invocationExpression.Expression?.Kind = SyntaxKind.SimpleMemberAccessExpression Then
Dim memberAccess = DirectCast(invocationExpression.Expression, MemberAccessExpressionSyntax)
Dim targetSymbol = semanticModel.GetSymbolInfo(memberAccess.Name)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册