Merge pull request #57 from icsharpcode/vb/improve-array-handling
VB -> C#: Improve array handling (Erase, ReDim, initializers)
This commit is contained in:
Коммит
e497e35cae
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ICSharpCode.CodeConverter.Shared;
|
||||
|
@ -6,6 +7,7 @@ using ICSharpCode.CodeConverter.Util;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using SyntaxFactory = Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
using VBasic = Microsoft.CodeAnalysis.VisualBasic;
|
||||
using VBSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax;
|
||||
|
||||
|
@ -101,6 +103,159 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
return SingleStatement(SyntaxFactory.AssignmentExpression(kind, (ExpressionSyntax)node.Left.Accept(nodesVisitor), (ExpressionSyntax)node.Right.Accept(nodesVisitor)));
|
||||
}
|
||||
|
||||
public override SyntaxList<StatementSyntax> VisitEraseStatement(VBSyntax.EraseStatementSyntax node)
|
||||
{
|
||||
var eraseStatements = node.Expressions.Select<VBSyntax.ExpressionSyntax, StatementSyntax>(arrayExpression => {
|
||||
var lhs = arrayExpression.Accept(nodesVisitor);
|
||||
var rhs = SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression);
|
||||
var assignmentExpressionSyntax =
|
||||
SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, (ExpressionSyntax)lhs,
|
||||
rhs);
|
||||
return SyntaxFactory.ExpressionStatement(assignmentExpressionSyntax);
|
||||
});
|
||||
return SyntaxFactory.List(eraseStatements);
|
||||
}
|
||||
|
||||
public override SyntaxList<StatementSyntax> VisitReDimStatement(VBSyntax.ReDimStatementSyntax node)
|
||||
{
|
||||
return SyntaxFactory.List(node.Clauses.SelectMany(arrayExpression => arrayExpression.Accept(CommentConvertingVisitor)));
|
||||
}
|
||||
|
||||
public override SyntaxList<StatementSyntax> VisitRedimClause(VBSyntax.RedimClauseSyntax node)
|
||||
{
|
||||
bool preserve = node.Parent is VBSyntax.ReDimStatementSyntax rdss && rdss.PreserveKeyword.IsKind(VBasic.SyntaxKind.PreserveKeyword);
|
||||
|
||||
var csTargetArrayExpression = (ExpressionSyntax) node.Expression.Accept(nodesVisitor);
|
||||
var convertedBounds = ConvertArrayBounds(node.ArrayBounds, semanticModel, nodesVisitor).ToList();
|
||||
|
||||
var newArrayAssignment = CreateNewArrayAssignment(node.Expression, csTargetArrayExpression, convertedBounds, node.SpanStart);
|
||||
if (!preserve) return SingleStatement(newArrayAssignment);
|
||||
|
||||
var oldTargetName = GetUniqueVariableNameInScope(node, "old" + csTargetArrayExpression.ToString().ToPascalCase());
|
||||
var oldArrayAssignment = CreateLocalVariableDeclarationAndAssignment(oldTargetName, csTargetArrayExpression);
|
||||
|
||||
var oldTargetExpression = SyntaxFactory.IdentifierName(oldTargetName);
|
||||
var arrayCopyIfNotNull = CreateConditionalArrayCopy(oldTargetExpression, csTargetArrayExpression, convertedBounds);
|
||||
|
||||
return SyntaxFactory.List(new StatementSyntax[] {oldArrayAssignment, newArrayAssignment, arrayCopyIfNotNull});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Cut down version of Microsoft.VisualBasic.CompilerServices.Utils.CopyArray
|
||||
/// </summary>
|
||||
private IfStatementSyntax CreateConditionalArrayCopy(IdentifierNameSyntax sourceArrayExpression,
|
||||
ExpressionSyntax targetArrayExpression,
|
||||
List<ExpressionSyntax> convertedBounds)
|
||||
{
|
||||
var sourceLength = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, sourceArrayExpression, SyntaxFactory.IdentifierName("Length"));
|
||||
var arrayCopyStatement = convertedBounds.Count == 1
|
||||
? CreateArrayCopyWithMinOfLengths(sourceArrayExpression, sourceLength, targetArrayExpression, convertedBounds.Single())
|
||||
: CreateArrayCopy(sourceArrayExpression, sourceLength, targetArrayExpression, convertedBounds);
|
||||
|
||||
var oldTargetNotEqualToNull = SyntaxFactory.BinaryExpression(SyntaxKind.NotEqualsExpression, sourceArrayExpression,
|
||||
SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression));
|
||||
return SyntaxFactory.IfStatement(oldTargetNotEqualToNull, arrayCopyStatement);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Array copy for multiple array dimensions represented by <paramref name="convertedBounds"/>
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Exception cases will sometimes silently succeed in the converted code,
|
||||
/// but existing VB code relying on the exception thrown from a multidimensional redim preserve on
|
||||
/// different rank arrays is hopefully rare enough that it's worth saving a few lines of code
|
||||
/// </remarks>
|
||||
private StatementSyntax CreateArrayCopy(IdentifierNameSyntax sourceArrayExpression,
|
||||
MemberAccessExpressionSyntax sourceLength,
|
||||
ExpressionSyntax targetArrayExpression, ICollection convertedBounds)
|
||||
{
|
||||
var lastSourceLengthArgs = CreateArgList(Literal(convertedBounds.Count - 1));
|
||||
var sourceLastRankLength = SyntaxFactory.InvocationExpression(
|
||||
SyntaxFactory.ParseExpression($"{sourceArrayExpression.Identifier}.GetLength"), lastSourceLengthArgs);
|
||||
var targetLastRankLength =
|
||||
SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression($"{targetArrayExpression}.GetLength"),
|
||||
lastSourceLengthArgs);
|
||||
var length = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("Math.Min"),
|
||||
CreateArgList(sourceLastRankLength, targetLastRankLength));
|
||||
|
||||
var loopVariableName = GetUniqueVariableNameInScope(sourceArrayExpression, "i");
|
||||
var loopVariableIdentifier = SyntaxFactory.IdentifierName(loopVariableName);
|
||||
var sourceStartForThisIteration =
|
||||
SyntaxFactory.BinaryExpression(SyntaxKind.MultiplyExpression, loopVariableIdentifier, sourceLastRankLength);
|
||||
var targetStartForThisIteration =
|
||||
SyntaxFactory.BinaryExpression(SyntaxKind.MultiplyExpression, loopVariableIdentifier, targetLastRankLength);
|
||||
|
||||
var arrayCopy = CreateArrayCopyWithStartingPoints(sourceArrayExpression, sourceStartForThisIteration, targetArrayExpression,
|
||||
targetStartForThisIteration, length);
|
||||
|
||||
var sourceArrayCount = SyntaxFactory.BinaryExpression(SyntaxKind.SubtractExpression,
|
||||
SyntaxFactory.BinaryExpression(SyntaxKind.DivideExpression, sourceLength, sourceLastRankLength),
|
||||
Literal(1));
|
||||
|
||||
return CreateForZeroToValueLoop(loopVariableIdentifier, arrayCopy, sourceArrayCount);
|
||||
}
|
||||
|
||||
private static ForStatementSyntax CreateForZeroToValueLoop(SimpleNameSyntax loopVariableIdentifier, StatementSyntax loopStatement, ExpressionSyntax inclusiveLoopUpperBound)
|
||||
{
|
||||
var loopVariableAssignment = CreateVariableDeclarationAndAssignment(loopVariableIdentifier.Identifier.Text, Literal(0));
|
||||
var lessThanSourceBounds = SyntaxFactory.BinaryExpression(SyntaxKind.LessThanOrEqualExpression,
|
||||
loopVariableIdentifier, inclusiveLoopUpperBound);
|
||||
var incrementors = SyntaxFactory.SingletonSeparatedList<ExpressionSyntax>(
|
||||
SyntaxFactory.PrefixUnaryExpression(SyntaxKind.PreIncrementExpression, loopVariableIdentifier));
|
||||
var forStatementSyntax = SyntaxFactory.ForStatement(loopVariableAssignment,
|
||||
SyntaxFactory.SeparatedList<ExpressionSyntax>(),
|
||||
lessThanSourceBounds, incrementors, loopStatement);
|
||||
return forStatementSyntax;
|
||||
}
|
||||
|
||||
private static ExpressionStatementSyntax CreateArrayCopyWithMinOfLengths(
|
||||
IdentifierNameSyntax sourceExpression, ExpressionSyntax sourceLength,
|
||||
ExpressionSyntax targetExpression, ExpressionSyntax targetLength)
|
||||
{
|
||||
var minLength = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("Math.Min"),
|
||||
CreateArgList(targetLength, sourceLength));
|
||||
var copyArgList = CreateArgList(sourceExpression, targetExpression, minLength);
|
||||
var arrayCopy = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("Array.Copy"), copyArgList);
|
||||
return SyntaxFactory.ExpressionStatement(arrayCopy);
|
||||
}
|
||||
|
||||
private static ExpressionStatementSyntax CreateArrayCopyWithStartingPoints(
|
||||
IdentifierNameSyntax sourceExpression, ExpressionSyntax sourceStart,
|
||||
ExpressionSyntax targetExpression, ExpressionSyntax targetStart, ExpressionSyntax length)
|
||||
{
|
||||
var copyArgList = CreateArgList(sourceExpression, sourceStart, targetExpression, targetStart, length);
|
||||
var arrayCopy = SyntaxFactory.InvocationExpression(SyntaxFactory.ParseExpression("Array.Copy"), copyArgList);
|
||||
return SyntaxFactory.ExpressionStatement(arrayCopy);
|
||||
}
|
||||
|
||||
private ExpressionStatementSyntax CreateNewArrayAssignment(VBSyntax.ExpressionSyntax vbArrayExpression,
|
||||
ExpressionSyntax csArrayExpression, List<ExpressionSyntax> convertedBounds,
|
||||
int nodeSpanStart)
|
||||
{
|
||||
var arrayRankSpecifierSyntax = SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.SeparatedList(convertedBounds));
|
||||
var convertedType = (IArrayTypeSymbol) semanticModel.GetTypeInfo(vbArrayExpression).ConvertedType;
|
||||
var typeSyntax = GetTypeSyntaxFromTypeSymbol(convertedType.ElementType, nodeSpanStart);
|
||||
var arrayCreation =
|
||||
SyntaxFactory.ArrayCreationExpression(SyntaxFactory.ArrayType(typeSyntax,
|
||||
SyntaxFactory.SingletonList(arrayRankSpecifierSyntax)));
|
||||
var assignmentExpressionSyntax =
|
||||
SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, csArrayExpression, arrayCreation);
|
||||
var newArrayAssignment = SyntaxFactory.ExpressionStatement(assignmentExpressionSyntax);
|
||||
return newArrayAssignment;
|
||||
}
|
||||
|
||||
private static ArgumentListSyntax CreateArgList(params ExpressionSyntax[] copyArgs)
|
||||
{
|
||||
return SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(copyArgs.Select(SyntaxFactory.Argument)));
|
||||
}
|
||||
|
||||
private TypeSyntax GetTypeSyntaxFromTypeSymbol(ITypeSymbol convertedType, int nodeSpanStart)
|
||||
{
|
||||
var predefinedKeywordKind = convertedType.SpecialType.GetPredefinedKeywordKind();
|
||||
if (predefinedKeywordKind != SyntaxKind.None) return SyntaxFactory.PredefinedType(SyntaxFactory.Token(predefinedKeywordKind));
|
||||
return SyntaxFactory.ParseTypeName(convertedType.ToMinimalDisplayString(semanticModel, nodeSpanStart));
|
||||
}
|
||||
|
||||
public override SyntaxList<StatementSyntax> VisitThrowStatement(VBSyntax.ThrowStatementSyntax node)
|
||||
{
|
||||
return SingleStatement(SyntaxFactory.ThrowStatement((ExpressionSyntax)node.Expression?.Accept(nodesVisitor)));
|
||||
|
@ -327,12 +482,7 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
var withExpression = (ExpressionSyntax)node.WithStatement.Expression.Accept(nodesVisitor);
|
||||
withBlockTempVariableNames.Push(GetUniqueVariableNameInScope(node, "withBlock"));
|
||||
try {
|
||||
var variableDeclaratorSyntax = SyntaxFactory.VariableDeclarator(
|
||||
SyntaxFactory.Identifier(withBlockTempVariableNames.Peek()), null,
|
||||
SyntaxFactory.EqualsValueClause(withExpression));
|
||||
var declaration = SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(
|
||||
SyntaxFactory.IdentifierName("var"),
|
||||
SyntaxFactory.SingletonSeparatedList(variableDeclaratorSyntax)));
|
||||
var declaration = CreateLocalVariableDeclarationAndAssignment(withBlockTempVariableNames.Peek(), withExpression);
|
||||
var statements = node.Statements.SelectMany(s => s.Accept(CommentConvertingVisitor));
|
||||
|
||||
return SingleStatement(SyntaxFactory.Block(new[] { declaration }.Concat(statements).ToArray()));
|
||||
|
@ -341,6 +491,23 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
}
|
||||
}
|
||||
|
||||
private LocalDeclarationStatementSyntax CreateLocalVariableDeclarationAndAssignment(string variableName, ExpressionSyntax initValue)
|
||||
{
|
||||
return SyntaxFactory.LocalDeclarationStatement(CreateVariableDeclarationAndAssignment(variableName, initValue));
|
||||
}
|
||||
|
||||
private static VariableDeclarationSyntax CreateVariableDeclarationAndAssignment(string variableName,
|
||||
ExpressionSyntax initValue)
|
||||
{
|
||||
var variableDeclaratorSyntax = SyntaxFactory.VariableDeclarator(
|
||||
SyntaxFactory.Identifier(variableName), null,
|
||||
SyntaxFactory.EqualsValueClause(initValue));
|
||||
var variableDeclarationSyntax = SyntaxFactory.VariableDeclaration(
|
||||
SyntaxFactory.IdentifierName("var"),
|
||||
SyntaxFactory.SingletonSeparatedList(variableDeclaratorSyntax));
|
||||
return variableDeclarationSyntax;
|
||||
}
|
||||
|
||||
private string GetUniqueVariableNameInScope(SyntaxNode node, string variableNameBase)
|
||||
{
|
||||
var reservedNames = withBlockTempVariableNames.Concat(node.DescendantNodesAndSelf()
|
||||
|
@ -435,6 +602,22 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
{
|
||||
return SyntaxFactory.SingletonList<StatementSyntax>(SyntaxFactory.ExpressionStatement(expression));
|
||||
}
|
||||
|
||||
public static IEnumerable<ExpressionSyntax> ConvertArrayBounds(VBSyntax.ArgumentListSyntax argumentListSyntax, SemanticModel model, VBasic.VisualBasicSyntaxVisitor<CSharpSyntaxNode> commentConvertingNodesVisitor)
|
||||
{
|
||||
return argumentListSyntax.Arguments.Select(a => IncreaseArrayUpperBoundExpression(((VBSyntax.SimpleArgumentSyntax)a).Expression, model, commentConvertingNodesVisitor));
|
||||
}
|
||||
|
||||
private static ExpressionSyntax IncreaseArrayUpperBoundExpression(VBSyntax.ExpressionSyntax expr, SemanticModel model, VBasic.VisualBasicSyntaxVisitor<CSharpSyntaxNode> commentConvertingNodesVisitor)
|
||||
{
|
||||
var constant = model.GetConstantValue(expr);
|
||||
if (constant.HasValue && constant.Value is int)
|
||||
return SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((int)constant.Value + 1));
|
||||
|
||||
return SyntaxFactory.BinaryExpression(
|
||||
SyntaxKind.SubtractExpression,
|
||||
(ExpressionSyntax)expr.Accept(commentConvertingNodesVisitor), SyntaxFactory.Token(SyntaxKind.PlusToken), SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -654,7 +654,7 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
returnType = returnType ?? SyntaxFactory.ParseTypeName("object");
|
||||
}
|
||||
|
||||
var rankSpecifiers = ConvertArrayRankSpecifierSyntaxes(node.Identifier.ArrayRankSpecifiers);
|
||||
var rankSpecifiers = ConvertArrayRankSpecifierSyntaxes(node.Identifier.ArrayRankSpecifiers, node.Identifier.ArrayBounds, TriviaConvertingVisitor, semanticModel, false);
|
||||
if (rankSpecifiers.Any() && returnType != null) {
|
||||
returnType = SyntaxFactory.ArrayType(returnType, rankSpecifiers);
|
||||
}
|
||||
|
@ -804,13 +804,13 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
if (node.Token.Value == null) {
|
||||
var type = semanticModel.GetTypeInfo(node).ConvertedType;
|
||||
if (type == null) {
|
||||
return Literal("null", null)
|
||||
return Literal(null, "null")
|
||||
.WithTrailingTrivia(
|
||||
SyntaxFactory.Comment("/* TODO Change to default(_) if this is not a reference type */"));
|
||||
}
|
||||
return !type.IsReferenceType ? SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(type.ToMinimalDisplayString(semanticModel, node.SpanStart))) : Literal("null", null);
|
||||
return !type.IsReferenceType ? SyntaxFactory.DefaultExpression(SyntaxFactory.ParseTypeName(type.ToMinimalDisplayString(semanticModel, node.SpanStart))) : Literal(null, "null");
|
||||
}
|
||||
return Literal(node.Token.Text, node.Token.Value);
|
||||
return Literal(node.Token.Value, node.Token.Text);
|
||||
}
|
||||
|
||||
public override CSharpSyntaxNode VisitInterpolatedStringExpression(VBSyntax.InterpolatedStringExpressionSyntax node)
|
||||
|
@ -1002,25 +1002,31 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
|
||||
public override CSharpSyntaxNode VisitArrayCreationExpression(VBSyntax.ArrayCreationExpressionSyntax node)
|
||||
{
|
||||
var bounds = ConvertArrayRankSpecifierSyntaxes(node.RankSpecifiers);
|
||||
if (node.ArrayBounds != null) {
|
||||
var arrayRankSpecifierSyntax = SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.SeparatedList(ConvertArrayBounds(node.ArrayBounds)));
|
||||
bounds = bounds.Insert(0, arrayRankSpecifierSyntax);
|
||||
}
|
||||
var bounds = ConvertArrayRankSpecifierSyntaxes(node.RankSpecifiers, node.ArrayBounds, TriviaConvertingVisitor, semanticModel);
|
||||
return SyntaxFactory.ArrayCreationExpression(
|
||||
SyntaxFactory.ArrayType((TypeSyntax)node.Type.Accept(TriviaConvertingVisitor), bounds),
|
||||
(InitializerExpressionSyntax)node.Initializer?.Accept(TriviaConvertingVisitor)
|
||||
);
|
||||
}
|
||||
|
||||
private SyntaxList<ArrayRankSpecifierSyntax> ConvertArrayRankSpecifierSyntaxes(SyntaxList<VBSyntax.ArrayRankSpecifierSyntax> arrayRankSpecifierSyntaxs)
|
||||
internal static SyntaxList<ArrayRankSpecifierSyntax> ConvertArrayRankSpecifierSyntaxes(
|
||||
SyntaxList<VBSyntax.ArrayRankSpecifierSyntax> arrayRankSpecifierSyntaxs,
|
||||
VBSyntax.ArgumentListSyntax nodeArrayBounds, VBasic.VisualBasicSyntaxVisitor<CSharpSyntaxNode> commentConvertingNodesVisitor, SemanticModel semanticModel, bool withSizes = true)
|
||||
{
|
||||
return SyntaxFactory.List(arrayRankSpecifierSyntaxs.Select(r => (ArrayRankSpecifierSyntax)r.Accept(TriviaConvertingVisitor)));
|
||||
}
|
||||
var bounds = SyntaxFactory.List(arrayRankSpecifierSyntaxs.Select(r => (ArrayRankSpecifierSyntax)r.Accept(commentConvertingNodesVisitor)));
|
||||
|
||||
private IEnumerable<ExpressionSyntax> ConvertArrayBounds(VBSyntax.ArgumentListSyntax argumentListSyntax)
|
||||
{
|
||||
return argumentListSyntax.Arguments.Select(a => IncreaseArrayUpperBoundExpression(((VBSyntax.SimpleArgumentSyntax)a).Expression));
|
||||
if (nodeArrayBounds != null)
|
||||
{
|
||||
var convertedArrayBounds = withSizes ?
|
||||
MethodBodyVisitor.ConvertArrayBounds(nodeArrayBounds, semanticModel, commentConvertingNodesVisitor)
|
||||
: nodeArrayBounds.Arguments.Select(s => SyntaxFactory.OmittedArraySizeExpression());
|
||||
var arrayRankSpecifierSyntax = SyntaxFactory.ArrayRankSpecifier(
|
||||
SyntaxFactory.SeparatedList(
|
||||
convertedArrayBounds));
|
||||
bounds = bounds.Insert(0, arrayRankSpecifierSyntax);
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
public override CSharpSyntaxNode VisitCollectionInitializer(VBSyntax.CollectionInitializerSyntax node)
|
||||
|
@ -1185,17 +1191,6 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
return node.Initializer.Accept(TriviaConvertingVisitor); //Dictionary initializer comes through here despite the FROM keyword not being in the source code
|
||||
}
|
||||
|
||||
ExpressionSyntax IncreaseArrayUpperBoundExpression(VBSyntax.ExpressionSyntax expr)
|
||||
{
|
||||
var constant = semanticModel.GetConstantValue(expr);
|
||||
if (constant.HasValue && constant.Value is int)
|
||||
return SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((int)constant.Value + 1));
|
||||
|
||||
return SyntaxFactory.BinaryExpression(
|
||||
SyntaxKind.SubtractExpression,
|
||||
(ExpressionSyntax)expr.Accept(TriviaConvertingVisitor), SyntaxFactory.Token(SyntaxKind.PlusToken), SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(1)));
|
||||
}
|
||||
|
||||
public override CSharpSyntaxNode VisitBinaryConditionalExpression(VBSyntax.BinaryConditionalExpressionSyntax node)
|
||||
{
|
||||
return SyntaxFactory.BinaryExpression(
|
||||
|
|
|
@ -61,13 +61,26 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
foreach (var name in declarator.Names) {
|
||||
var type = rawType;
|
||||
if (!SyntaxTokenExtensions.IsKind(name.Nullable, VBasic.SyntaxKind.None)) {
|
||||
if (type is ArrayTypeSyntax)
|
||||
type = ((ArrayTypeSyntax)type).WithElementType(SyntaxFactory.NullableType(((ArrayTypeSyntax)type).ElementType));
|
||||
else
|
||||
if (type is ArrayTypeSyntax) {
|
||||
type = ((ArrayTypeSyntax)type).WithElementType(
|
||||
SyntaxFactory.NullableType(((ArrayTypeSyntax)type).ElementType));
|
||||
initializer = null;
|
||||
} else
|
||||
type = SyntaxFactory.NullableType(type);
|
||||
}
|
||||
if (name.ArrayRankSpecifiers.Count > 0)
|
||||
type = SyntaxFactory.ArrayType(type, SyntaxFactory.List(name.ArrayRankSpecifiers.Select(a => (ArrayRankSpecifierSyntax)a.Accept(nodesVisitor))));
|
||||
|
||||
var rankSpecifiers = NodesVisitor.ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, nodesVisitor, semanticModel, false);
|
||||
if (rankSpecifiers.Count > 0) {
|
||||
var rankSpecifiersWithSizes = NodesVisitor.ConvertArrayRankSpecifierSyntaxes(name.ArrayRankSpecifiers, name.ArrayBounds, nodesVisitor, semanticModel);
|
||||
if (!rankSpecifiersWithSizes.SelectMany(ars => ars.Sizes).OfType<OmittedArraySizeExpressionSyntax>().Any())
|
||||
{
|
||||
initializer =
|
||||
SyntaxFactory.ArrayCreationExpression(
|
||||
SyntaxFactory.ArrayType(type, rankSpecifiersWithSizes));
|
||||
}
|
||||
type = SyntaxFactory.ArrayType(type, rankSpecifiers);
|
||||
}
|
||||
|
||||
VariableDeclarationSyntax decl;
|
||||
var v = SyntaxFactory.VariableDeclarator(ConvertIdentifier(name.Identifier, semanticModel), null, initializer == null ? null : SyntaxFactory.EqualsValueClause(initializer));
|
||||
string k = type.ToString();
|
||||
|
@ -80,7 +93,7 @@ namespace ICSharpCode.CodeConverter.CSharp
|
|||
return newDecls;
|
||||
}
|
||||
|
||||
static ExpressionSyntax Literal(string valueText, object o) => GetLiteralExpression(valueText, o);
|
||||
static ExpressionSyntax Literal(object o, string valueText = null) => GetLiteralExpression(valueText ?? o.ToString(), o);
|
||||
|
||||
internal static ExpressionSyntax GetLiteralExpression(string valueText, object value)
|
||||
{
|
||||
|
|
|
@ -1971,7 +1971,7 @@ namespace ICSharpCode.CodeConverter.Util
|
|||
/// </summary>
|
||||
/// <param name="specialType">The specialtype of this type.</param>
|
||||
/// <returns>The keyword kind for a given special type, or SyntaxKind.None if the type name is not a predefined type.</returns>
|
||||
public static SyntaxKind GetPredefinedKeywordKind(SpecialType specialType)
|
||||
public static SyntaxKind GetPredefinedKeywordKind(this SpecialType specialType)
|
||||
{
|
||||
switch (specialType) {
|
||||
case SpecialType.System_Boolean:
|
||||
|
|
|
@ -194,6 +194,48 @@ class TestClass
|
|||
}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ArrayEraseAndRedimStatement()
|
||||
{
|
||||
// One statement turns into two, so can't auto-test comments
|
||||
TestConversionVisualBasicToCSharpWithoutComments(@"Public Class TestClass
|
||||
Shared Function TestMethod(numArray As Integer(), numArray2 As Integer()) As Integer()
|
||||
ReDim numArray(3)
|
||||
Erase numArray
|
||||
numArray2(1) = 1
|
||||
ReDim Preserve numArray(5), numArray2(5)
|
||||
Dim y(6, 5) As Integer
|
||||
y(2,3) = 1
|
||||
ReDim Preserve y(6,8)
|
||||
Return numArray2
|
||||
End Function
|
||||
End Class", @"public class TestClass
|
||||
{
|
||||
public static int[] TestMethod(int[] numArray, int[] numArray2)
|
||||
{
|
||||
numArray = new int[4];
|
||||
numArray = null;
|
||||
numArray2[1] = 1;
|
||||
var oldNumArray = numArray;
|
||||
numArray = new int[6];
|
||||
if (oldNumArray != null)
|
||||
Array.Copy(oldNumArray, numArray, Math.Min(6, oldNumArray.Length));
|
||||
var oldNumArray2 = numArray2;
|
||||
numArray2 = new int[6];
|
||||
if (oldNumArray2 != null)
|
||||
Array.Copy(oldNumArray2, numArray2, Math.Min(6, oldNumArray2.Length));
|
||||
int[,] y = new int[7, 6];
|
||||
y[2, 3] = 1;
|
||||
var oldY = y;
|
||||
y = new int[7, 9];
|
||||
if (oldY != null)
|
||||
for (var i = 0; i <= oldY.Length / oldY.GetLength(1) - 1; ++i)
|
||||
Array.Copy(oldY, i * oldY.GetLength(1), y, i * y.GetLength(1), Math.Min(oldY.GetLength(1), y.GetLength(1)));
|
||||
return numArray2;
|
||||
}
|
||||
}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void EndStatement()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче