Skip to content

Commit b992939

Browse files
Jules was unable to complete the task in time. Please review the work done so far and provide feedback for Jules to continue.
1 parent 9cfa6dd commit b992939

File tree

9 files changed

+3933
-3826
lines changed

9 files changed

+3933
-3826
lines changed

CodeConverter/CSharp/ExpressionNodeVisitor.Arguments.cs

Lines changed: 402 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
using System.Collections.Immutable;
2+
//using System.Data; // Not directly used by lambda methods
3+
using System.Globalization;
4+
//using System.Linq.Expressions; // Not directly used by lambda methods
5+
//using System.Runtime.CompilerServices;
6+
//using System.Xml.Linq; // Not used
7+
//using ICSharpCode.CodeConverter.CSharp.Replacements; // Not directly used
8+
using ICSharpCode.CodeConverter.Util.FromRoslyn; // For .Yield()
9+
using Microsoft.CodeAnalysis.CSharp;
10+
using Microsoft.CodeAnalysis.CSharp.Syntax;
11+
//using Microsoft.CodeAnalysis.Operations; // Not directly used
12+
//using Microsoft.CodeAnalysis.Simplification; // Not directly used
13+
//using Microsoft.VisualBasic; // Not directly used
14+
//using Microsoft.VisualBasic.CompilerServices; // Not directly used
15+
//using ComparisonKind = ICSharpCode.CodeConverter.CSharp.VisualBasicEqualityComparison.ComparisonKind; // Not used
16+
using System.Threading.Tasks;
17+
using System;
18+
using System.Linq;
19+
using System.Collections.Generic;
20+
using VBSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax;
21+
22+
namespace ICSharpCode.CodeConverter.CSharp;
23+
24+
internal partial class ExpressionNodeVisitor // Must be partial
25+
{
26+
private readonly LambdaConverter _lambdaConverter;
27+
28+
public override async Task<CSharpSyntaxNode> VisitSingleLineLambdaExpression(VBasic.Syntax.SingleLineLambdaExpressionSyntax node)
29+
{
30+
var originalIsWithinQuery = TriviaConvertingExpressionVisitor.IsWithinQuery;
31+
TriviaConvertingExpressionVisitor.IsWithinQuery = CommonConversions.IsLinqDelegateExpression(node);
32+
try {
33+
return await ConvertInnerAsync();
34+
} finally {
35+
TriviaConvertingExpressionVisitor.IsWithinQuery = originalIsWithinQuery;
36+
}
37+
38+
async Task<CSharpSyntaxNode> ConvertInnerAsync()
39+
{
40+
IReadOnlyCollection<StatementSyntax> convertedStatements;
41+
if (node.Body is VBasic.Syntax.StatementSyntax statement)
42+
{
43+
convertedStatements = await ConvertMethodBodyStatementsAsync(statement, statement.Yield().ToArray());
44+
}
45+
else
46+
{
47+
var csNode = await node.Body.AcceptAsync<ExpressionSyntax>(TriviaConvertingExpressionVisitor);
48+
convertedStatements = new[] {SyntaxFactory.ExpressionStatement(csNode)};
49+
}
50+
51+
var param = await node.SubOrFunctionHeader.ParameterList.AcceptAsync<ParameterListSyntax>(TriviaConvertingExpressionVisitor);
52+
return await _lambdaConverter.ConvertAsync(node, param, convertedStatements);
53+
}
54+
}
55+
56+
public override async Task<CSharpSyntaxNode> VisitMultiLineLambdaExpression(VBasic.Syntax.MultiLineLambdaExpressionSyntax node)
57+
{
58+
var originalIsWithinQuery = TriviaConvertingExpressionVisitor.IsWithinQuery;
59+
TriviaConvertingExpressionVisitor.IsWithinQuery = CommonConversions.IsLinqDelegateExpression(node);
60+
try {
61+
return await ConvertInnerAsync();
62+
} finally {
63+
TriviaConvertingExpressionVisitor.IsWithinQuery = originalIsWithinQuery;
64+
}
65+
66+
async Task<CSharpSyntaxNode> ConvertInnerAsync()
67+
{
68+
var body = await ConvertMethodBodyStatementsAsync(node, node.Statements);
69+
var param = await node.SubOrFunctionHeader.ParameterList.AcceptAsync<ParameterListSyntax>(TriviaConvertingExpressionVisitor);
70+
return await _lambdaConverter.ConvertAsync(node, param, body.ToList());
71+
}
72+
}
73+
74+
public async Task<IReadOnlyCollection<StatementSyntax>> ConvertMethodBodyStatementsAsync(VBasic.VisualBasicSyntaxNode node, IReadOnlyCollection<VBSyntax.StatementSyntax> statements, bool isIterator = false, IdentifierNameSyntax csReturnVariable = null)
75+
{
76+
// _visualBasicEqualityComparison and _withBlockLhs are accessed via `this` from other partial classes
77+
var innerMethodBodyVisitor = await MethodBodyExecutableStatementVisitor.CreateAsync(node, _semanticModel, TriviaConvertingExpressionVisitor, CommonConversions, _visualBasicEqualityComparison, new Stack<ExpressionSyntax>(), _extraUsingDirectives, _typeContext, isIterator, csReturnVariable);
78+
return await GetWithConvertedGotosOrNull(statements) ?? await ConvertStatements(statements);
79+
80+
async Task<List<StatementSyntax>> ConvertStatements(IEnumerable<VBSyntax.StatementSyntax> readOnlyCollection)
81+
{
82+
return (await readOnlyCollection.SelectManyAsync(async s => (IEnumerable<StatementSyntax>)await s.Accept(innerMethodBodyVisitor.CommentConvertingVisitor))).ToList();
83+
}
84+
85+
async Task<IReadOnlyCollection<StatementSyntax>> GetWithConvertedGotosOrNull(IReadOnlyCollection<VBSyntax.StatementSyntax> stmts)
86+
{
87+
var onlyIdentifierLabel = stmts.OnlyOrDefault(s => s.IsKind(VBasic.SyntaxKind.LabelStatement));
88+
var onlyOnErrorGotoStatement = stmts.OnlyOrDefault(s => s.IsKind(VBasic.SyntaxKind.OnErrorGoToLabelStatement));
89+
90+
// See https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/on-error-statement
91+
if (onlyIdentifierLabel != null && onlyOnErrorGotoStatement != null) {
92+
var statementsList = stmts.ToList();
93+
var onlyIdentifierLabelIndex = statementsList.IndexOf(onlyIdentifierLabel);
94+
var onlyOnErrorGotoStatementIndex = statementsList.IndexOf(onlyOnErrorGotoStatement);
95+
96+
if (onlyOnErrorGotoStatementIndex < onlyIdentifierLabelIndex) {
97+
var beforeStatements = await ConvertStatements(stmts.Take(onlyOnErrorGotoStatementIndex));
98+
var tryBlockStatements = await ConvertStatements(stmts.Take(onlyIdentifierLabelIndex).Skip(onlyOnErrorGotoStatementIndex + 1));
99+
var tryBlock = SyntaxFactory.Block(tryBlockStatements);
100+
var afterStatements = await ConvertStatements(stmts.Skip(onlyIdentifierLabelIndex + 1));
101+
102+
var catchClauseSyntax = SyntaxFactory.CatchClause();
103+
104+
if (tryBlockStatements.LastOrDefault().IsKind(SyntaxKind.ReturnStatement)) {
105+
catchClauseSyntax = catchClauseSyntax.WithBlock(SyntaxFactory.Block(afterStatements));
106+
afterStatements = new List<StatementSyntax>();
107+
}
108+
109+
var tryStatement = SyntaxFactory.TryStatement(SyntaxFactory.SingletonList(catchClauseSyntax)).WithBlock(tryBlock);
110+
return beforeStatements.Append(tryStatement).Concat(afterStatements).ToList();
111+
}
112+
}
113+
return null;
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)