Merge pull request #57 from icsharpcode/vb/improve-array-handling

VB -> C#: Improve array handling (Erase, ReDim, initializers)
This commit is contained in:
GrahamTheCoder 2018-03-19 12:21:54 +00:00 коммит произвёл GitHub
Родитель 598bffe20f 88c3a86b35
Коммит e497e35cae
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 272 добавлений и 39 удалений

Просмотреть файл

@ -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()
{