提交 352c4fdd 编写于 作者: C Cyrus Najmabadi

Add VB impl.

上级 f2f9d203
......@@ -27,8 +27,8 @@ private static bool IsAnyQueryClause(SyntaxNode node)
var oldOutermostQuery = expression.GetAncestorsOrThis<QueryExpressionSyntax>().LastOrDefault();
var newLocalNameToken = GenerateUniqueLocalName(
document, expression, isConstant: false,
container: oldOutermostQuery, cancellationToken: cancellationToken);
document, expression, isConstant: false,
containerOpt: oldOutermostQuery, cancellationToken: cancellationToken);
var newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken);
var letClause = SyntaxFactory.LetClause(
......
......@@ -62,12 +62,17 @@ public override async Task ComputeRefactoringsAsync(CodeRefactoringContext conte
return;
}
var forStatement = token.Parent as TForStatementSyntax;
var forStatement = token.Parent.AncestorsAndSelf().OfType<TForStatementSyntax>().FirstOrDefault();
if (forStatement == null)
{
return;
}
if (forStatement.GetFirstToken() != token)
{
return;
}
if (!TryGetForStatementComponents(forStatement,
out var iterationVariable, out var initializer,
out var memberAccess, out var stepValueOpt, cancellationToken))
......@@ -296,7 +301,7 @@ bool IterationVariableIsUsedForMoreThanCollectionIndex(SyntaxNode current)
syntaxFacts.GetInitializerOfVariableDeclarator(firstVariable));
if (syntaxFacts.AreEquivalent(firstVariableInitializer, indexExpression))
{
typeNode = (TTypeNode)syntaxFacts.GetTypeOfVariableDeclarator(firstVariable).WithoutLeadingTrivia();
typeNode = (TTypeNode)syntaxFacts.GetTypeOfVariableDeclarator(firstVariable)?.WithoutLeadingTrivia();
foreachIdentifier = syntaxFacts.GetIdentifierOfVariableDeclarator(firstVariable);
declarationStatement = firstStatement;
}
......@@ -307,8 +312,9 @@ bool IterationVariableIsUsedForMoreThanCollectionIndex(SyntaxNode current)
if (foreachIdentifier.RawKind == 0)
{
foreachIdentifier = semanticFacts.GenerateUniqueName(semanticModel, forStatement, "v", cancellationToken)
.WithAdditionalAnnotations(RenameAnnotation.Create());
foreachIdentifier = semanticFacts.GenerateUniqueName(
semanticModel, forStatement, containerOpt: null, baseName: "v", cancellationToken);
foreachIdentifier = foreachIdentifier.WithAdditionalAnnotations(RenameAnnotation.Create());
}
var foreachIdentifierName = generator.IdentifierName(foreachIdentifier).WithoutTrivia().WithoutAnnotations();
......
......@@ -218,7 +218,7 @@ private CodeAction CreateAction(State state, bool allOccurrences, bool isConstan
SemanticDocument document,
TExpressionSyntax expression,
bool isConstant,
SyntaxNode container,
SyntaxNode containerOpt,
CancellationToken cancellationToken)
{
var semanticModel = document.SemanticModel;
......@@ -227,7 +227,8 @@ private CodeAction CreateAction(State state, bool allOccurrences, bool isConstan
var baseName = semanticFacts.GenerateNameForExpression(
semanticModel, expression, capitalize: isConstant, cancellationToken: cancellationToken);
return semanticFacts.GenerateUniqueName(semanticModel, container, baseName, cancellationToken);
return semanticFacts.GenerateUniqueName(
semanticModel, expression, containerOpt, baseName, cancellationToken);
}
protected ISet<TExpressionSyntax> FindMatches(
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Composition
Imports System.Threading
Imports Microsoft.CodeAnalysis.CodeRefactorings
Imports Microsoft.CodeAnalysis.ConvertForToForEach
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic.ConvertForToForEach
<ExportCodeRefactoringProvider(LanguageNames.VisualBasic, Name:=NameOf(VisualBasicConvertForToForEachCodeRefactoringProvider)), [Shared]>
Friend Class VisualBasicConvertForToForEachCodeRefactoringProvider
Inherits AbstractConvertForToForEachCodeRefactoringProvider(Of
StatementSyntax,
ForBlockSyntax,
ExpressionSyntax,
MemberAccessExpressionSyntax,
TypeSyntax,
VariableDeclaratorSyntax)
Protected Overrides Function GetTitle() As String
Return VBFeaturesResources.Convert_For_to_For_Each
End Function
Protected Overrides Function GetBodyStatements(forStatement As ForBlockSyntax) As SyntaxList(Of StatementSyntax)
Return forStatement.Statements
End Function
Protected Overrides Function IsValidVariableDeclarator(firstVariable As VariableDeclaratorSyntax) As Boolean
' we only support local declarations in vb that have a single identifier. i.e.
' dim x = list(i)
Return firstVariable.Names.Count = 1
End Function
Protected Overrides Function TryGetForStatementComponents(
forBlock As ForBlockSyntax,
ByRef iterationVariable As SyntaxToken,
ByRef initializer As ExpressionSyntax,
ByRef memberAccess As MemberAccessExpressionSyntax,
ByRef stepValue As ExpressionSyntax,
cancellationToken As CancellationToken) As Boolean
Dim forStatement As ForStatementSyntax = forBlock.ForStatement
Dim identifierName = TryCast(forStatement.ControlVariable, IdentifierNameSyntax)
If identifierName IsNot Nothing Then
iterationVariable = identifierName.Identifier
If forStatement.FromValue IsNot Nothing Then
initializer = forStatement.FromValue
Dim subtraction = TryCast(forStatement.ToValue, BinaryExpressionSyntax)
If subtraction?.Kind() = SyntaxKind.SubtractExpression Then
Dim subtractionRight = TryCast(subtraction.Right, LiteralExpressionSyntax)
If TypeOf subtractionRight.Token.Value Is Integer AndAlso
DirectCast(subtractionRight.Token.Value, Integer) = 1 Then
memberAccess = TryCast(subtraction.Left, MemberAccessExpressionSyntax)
If memberAccess IsNot Nothing Then
stepValue = forStatement.StepClause?.StepValue
Return True
End If
End If
End If
End If
End If
Return False
End Function
Protected Overrides Function ConvertForNode(
currentFor As ForBlockSyntax, typeNode As TypeSyntax,
foreachIdentifier As SyntaxToken, collectionExpression As ExpressionSyntax, iterationVariableType As ITypeSymbol, options As OptionSet) As SyntaxNode
Dim forStatement = currentFor.ForStatement
Return SyntaxFactory.ForEachBlock(
SyntaxFactory.ForEachStatement(
SyntaxFactory.Token(SyntaxKind.ForKeyword).WithTriviaFrom(forStatement.ForKeyword),
SyntaxFactory.Token(SyntaxKind.EachKeyword),
SyntaxFactory.VariableDeclarator(
SyntaxFactory.SingletonSeparatedList(SyntaxFactory.ModifiedIdentifier(foreachIdentifier)),
If(typeNode IsNot Nothing, SyntaxFactory.SimpleAsClause(typeNode), Nothing),
Nothing),
SyntaxFactory.Token(SyntaxKind.InKeyword),
collectionExpression).WithTriviaFrom(forStatement),
currentFor.Statements,
currentFor.NextStatement)
End Function
End Class
End Namespace
......@@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable
Nothing)
Dim newNameToken = GenerateUniqueLocalName(
document, expression, isConstant, container:=Nothing,
document, expression, isConstant, containerOpt:=Nothing,
cancellationToken:=cancellationToken)
Dim newQualifiedName = SyntaxFactory.SimpleMemberAccessExpression(
......
......@@ -18,7 +18,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.IntroduceVariable
Dim newLocalNameToken = GenerateUniqueLocalName(
document, expression, isConstant:=False,
container:=oldOutermostQuery, cancellationToken:=cancellationToken)
containerOpt:=oldOutermostQuery, cancellationToken:=cancellationToken)
Dim newLocalName = SyntaxFactory.IdentifierName(newLocalNameToken)
Dim letClause = SyntaxFactory.LetClause(
......
......@@ -476,6 +476,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Convert &apos;For&apos; to &apos;For Each&apos;.
'''</summary>
Friend ReadOnly Property Convert_For_to_For_Each() As String
Get
Return ResourceManager.GetString("Convert_For_to_For_Each", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to Convert &apos;If&apos; to &apos;Select Case&apos;.
'''</summary>
......@@ -3353,7 +3362,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.VBFeaturesResources
Return ResourceManager.GetString("Using_statement", resourceCulture)
End Get
End Property
'''<summary>
''' Looks up a localized string similar to When a run-time error occurs, execution transfers to the statement following the statement or procedure call that resulted in the error..
'''</summary>
......
......@@ -1247,4 +1247,7 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</value>
<data name="Use_IsNot_Nothing_check" xml:space="preserve">
<value>Use 'IsNot Nothing' check</value>
</data>
<data name="Convert_For_to_For_Each" xml:space="preserve">
<value>Convert 'For' to 'For Each'</value>
</data>
</root>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;seznam_parametrů&gt;) &lt;výraz&gt;</target>
<target state="translated">Použít kontrolu „IsNot Nothing“</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;Parameterliste&gt;) &lt;Ausdruck&gt;</target>
<target state="translated">Prüfung "IsNot Nothing" verwenden</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;listaDeParámetros&gt;) &lt;instrucción&gt;</target>
<target state="translated">Usar comprobación "IsNot Nothing"</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">Utiliser la vérification 'IsNot Nothing'</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;elencoParametri&gt;) &lt;istruzione&gt;</target>
<target state="translated">Usa controllo 'IsNot Nothing'</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1816,6 +1816,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">IsNot Nothing' チェックを使用します</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">IsNot Nothing' 검사 사용</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;listaParametrów&gt;) &lt;instrukcja&gt;</target>
<target state="translated">Użyj sprawdzania „IsNot Nothing”</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">Usar a verificação 'IsNot Nothing'</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">Использовать флажок "IsNot Nothing"</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">IsNot Nothing' denetimi kullan</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">使用 "IsNot Nothing" 检查</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -1817,6 +1817,11 @@ Sub(&lt;parameterList&gt;) &lt;statement&gt;</target>
<target state="translated">使用 'IsNot Nothing' 檢查</target>
<note />
</trans-unit>
<trans-unit id="Convert_For_to_For_Each">
<source>Convert 'For' to 'For Each'</source>
<target state="new">Convert 'For' to 'For Each'</target>
<note />
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
......@@ -105,22 +105,26 @@ internal interface ISemanticFactsService : ILanguageService
SymbolInfo GetSymbolInfo(SemanticModel semanticModel, SyntaxNode node, SyntaxToken token, CancellationToken cancellationToken);
SyntaxToken GenerateUniqueName(SemanticModel semanticModel, SyntaxNode location, string baseName, CancellationToken cancellationToken);
SyntaxToken GenerateUniqueName(
SemanticModel semanticModel, SyntaxNode location,
SyntaxNode containerOpt, string baseName, CancellationToken cancellationToken);
}
internal abstract class AbstractSemanticFactsService
{
protected abstract ISyntaxFactsService SyntaxFactsService { get; }
public SyntaxToken GenerateUniqueName(SemanticModel semanticModel, SyntaxNode location, string baseName, CancellationToken cancellationToken)
public SyntaxToken GenerateUniqueName(
SemanticModel semanticModel, SyntaxNode location, SyntaxNode containerOpt,
string baseName, CancellationToken cancellationToken)
{
var syntaxFacts = this.SyntaxFactsService;
var container = location.AncestorsAndSelf().FirstOrDefault(
a => syntaxFacts.IsExecutableBlock(a) || syntaxFacts.IsMethodBody(a)) ?? location;
var container = containerOpt ?? location.AncestorsAndSelf().FirstOrDefault(
a => syntaxFacts.IsExecutableBlock(a) || syntaxFacts.IsMethodBody(a));
var existingSymbols = semanticModel.GetExistingSymbols(container, cancellationToken);
var reservedNames = semanticModel.LookupSymbols(container.SpanStart)
var reservedNames = semanticModel.LookupSymbols(location.SpanStart)
.Select(s => s.Name)
.Concat(existingSymbols.Select(s => s.Name));
......
......@@ -298,8 +298,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return semanticModel.GetSymbolInfo(node, cancellationToken)
End Function
Private Function ISemanticFactsService_GenerateUniqueName(semanticModel As SemanticModel, location As SyntaxNode, baseName As String, cancellationToken As CancellationToken) As SyntaxToken Implements ISemanticFactsService.GenerateUniqueName
Return MyBase.GenerateUniqueName(semanticModel, location, baseName, cancellationToken)
Private Function ISemanticFactsService_GenerateUniqueName(semanticModel As SemanticModel, location As SyntaxNode, containerOpt As SyntaxNode, baseName As String, cancellationToken As CancellationToken) As SyntaxToken Implements ISemanticFactsService.GenerateUniqueName
Return MyBase.GenerateUniqueName(semanticModel, location, containerOpt, baseName, cancellationToken)
End Function
End Class
End Namespace
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册