|
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeActions
Imports Microsoft.CodeAnalysis.Formatting
Imports Microsoft.CodeAnalysis.Simplification
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.CodeRefactorings.InlineTemporary
Partial Friend Class VisualBasicInlineTemporaryCodeRefactoringProvider
Partial Private Class ReferenceRewriter
Inherits VisualBasicSyntaxRewriter
Private ReadOnly _semanticModel As SemanticModel
Private ReadOnly _definition As ModifiedIdentifierSyntax
Private ReadOnly _expressionToInline As ExpressionSyntax
Private ReadOnly _cancellationToken As CancellationToken
Private ReadOnly _localSymbol As ILocalSymbol
Public Sub New(
semanticModel As SemanticModel,
modifiedIdentifier As ModifiedIdentifierSyntax,
expressionToInline As ExpressionSyntax,
cancellationToken As CancellationToken
)
_definition = modifiedIdentifier
_semanticModel = semanticModel
_expressionToInline = expressionToInline
_cancellationToken = cancellationToken
_localSymbol = DirectCast(_semanticModel.GetDeclaredSymbol(_definition, cancellationToken), ILocalSymbol)
End Sub
Private Function IsReference(node As SimpleNameSyntax) As Boolean
If Not CaseInsensitiveComparison.Equals(node.Identifier.ValueText, _definition.Identifier.ValueText) Then
Return False
End If
Dim symbolInfo = _semanticModel.GetSymbolInfo(node)
Return Equals(symbolInfo.Symbol, _localSymbol)
End Function
Public Overrides Function VisitIdentifierName(node As IdentifierNameSyntax) As SyntaxNode
_cancellationToken.ThrowIfCancellationRequested()
If IsReference(node) Then
If HasConflict(node, _definition, _expressionToInline, _semanticModel) Then
Return node.Update(node.Identifier.WithAdditionalAnnotations(
ConflictAnnotation.Create(VBFeaturesResources.Conflict_s_detected)))
End If
' Make sure we attach any trailing trivia from the identifier node we're replacing
' to the new expression so that we don't remove any line continuation characters.
Return _expressionToInline _
.Parenthesize() _
.WithTrailingTrivia(node.GetTrailingTrivia()) _
.WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation)
End If
Return MyBase.VisitIdentifierName(node)
End Function
Public Overrides Function VisitNameColonEquals(node As NameColonEqualsSyntax) As SyntaxNode
If node.IsParentKind(SyntaxKind.SimpleArgument) AndAlso
node.Parent.IsParentKind(SyntaxKind.TupleExpression) Then
' Temporaries should not be inlined in the name portion of a named tuple element
' This special case should be removed once https://github.com/dotnet/roslyn/issues/16697 is fixed
Return node
End If
Return MyBase.VisitNameColonEquals(node)
End Function
Public Overloads Shared Function Visit(
semanticModel As SemanticModel,
scope As SyntaxNode,
modifiedIdentifier As ModifiedIdentifierSyntax,
expressionToInline As ExpressionSyntax,
cancellationToken As CancellationToken
) As SyntaxNode
Dim rewriter = New ReferenceRewriter(semanticModel, modifiedIdentifier, expressionToInline, cancellationToken)
Return rewriter.Visit(scope)
End Function
End Class
End Class
End Namespace
|