public async Task <CSharpSyntaxNode> Convert(VBSyntax.LambdaExpressionSyntax vbNode, ParameterListSyntax param, IReadOnlyCollection <StatementSyntax> convertedStatements) { BlockSyntax block = null; ExpressionSyntax expressionBody = null; ArrowExpressionClauseSyntax arrow = null; if (convertedStatements.TryUnpackSingleStatement(out StatementSyntax singleStatement) && singleStatement.TryUnpackSingleExpressionFromStatement(out expressionBody)) { arrow = SyntaxFactory.ArrowExpressionClause(expressionBody); }
private async Task <CSharpSyntaxNode> ConvertToFunctionDeclarationOrNull(VBSyntax.LambdaExpressionSyntax vbNode, ParameterListSyntax param, BlockSyntax block, ArrowExpressionClauseSyntax arrow) { if (!(_semanticModel.GetOperation(vbNode) is IAnonymousFunctionOperation anonFuncOp)) { return(null); } var potentialAncestorDeclarationOperation = anonFuncOp.GetParentIgnoringConversions(); // Could do: See if we can improve upon returning "object" for pretty much everything (which is what the symbols say) // I believe that in general, special VB functions such as MultiplyObject are designed to work the same as integer when given two integers for example. // If all callers currently pass an integer, perhaps it'd be more idiomatic in C# to specify "int", than to have Operators var paramsWithTypes = anonFuncOp.Symbol.Parameters.Select(p => CommonConversions.CsSyntaxGenerator.ParameterDeclaration(p)); var paramListWithTypes = param.WithParameters(SyntaxFactory.SeparatedList(paramsWithTypes)); if (potentialAncestorDeclarationOperation is IFieldInitializerOperation fieldInit) { var fieldSymbol = fieldInit.InitializedFields.Single(); if (fieldSymbol.GetResultantVisibility() != SymbolVisibility.Public && !fieldSymbol.Type.IsDelegateReferencableByName() && await _solution.IsNeverWritten(fieldSymbol)) { return(CreateMethodDeclaration(anonFuncOp, fieldSymbol, block, arrow)); } } if (potentialAncestorDeclarationOperation is IVariableInitializerOperation vio) { if (vio.GetParentIgnoringConversions() is IVariableDeclarationGroupOperation go) { potentialAncestorDeclarationOperation = go.Declarations.First(d => d.Syntax.FullSpan.Contains(vbNode.FullSpan)); } else { potentialAncestorDeclarationOperation = vio.Parent; } if (potentialAncestorDeclarationOperation is IVariableDeclarationOperation variableDeclaration) { var variableDeclaratorOperation = variableDeclaration.Declarators.Single(); if (!variableDeclaratorOperation.Symbol.Type.IsDelegateReferencableByName() && await _solution.IsNeverWritten(variableDeclaratorOperation.Symbol)) { //Should do: Check no (other) write usages exist: SymbolFinder.FindReferencesAsync + checking if they're an assignment LHS or out parameter return(CreateLocalFunction(anonFuncOp, variableDeclaratorOperation, paramListWithTypes, block, arrow)); } } } return(null); }
public async Task <CSharpSyntaxNode> ConvertAsync(VBSyntax.LambdaExpressionSyntax vbNode, ParameterListSyntax param, IReadOnlyCollection <StatementSyntax> convertedStatements) { BlockSyntax block = null; ExpressionSyntax expressionBody = null; ArrowExpressionClauseSyntax arrow = null; if (!convertedStatements.TryUnpackSingleStatement(out StatementSyntax singleStatement)) { convertedStatements = convertedStatements.Select(l => l.WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed)).ToList(); block = SyntaxFactory.Block(convertedStatements); } else if (singleStatement.TryUnpackSingleExpressionFromStatement(out expressionBody)) { arrow = SyntaxFactory.ArrowExpressionClause(expressionBody); } else { block = SyntaxFactory.Block(singleStatement); } var functionStatement = await ConvertToFunctionDeclarationOrNullAsync(vbNode, param, block, arrow); if (functionStatement != null) { return(functionStatement); } var body = (CSharpSyntaxNode)block ?? expressionBody; var isAnonAsync = _semanticModel.GetOperation(vbNode) is IAnonymousFunctionOperation a && a.Symbol.IsAsync; var asyncKeyword = SyntaxFactory.Token(SyntaxKind.AsyncKeyword); LambdaExpressionSyntax lambda; if (param.Parameters.Count == 1 && param.Parameters.Single().Type == null) { var l = SyntaxFactory.SimpleLambdaExpression(param.Parameters[0], body); lambda = isAnonAsync ? l.WithAsyncKeyword(asyncKeyword) : l; } else { var l = SyntaxFactory.ParenthesizedLambdaExpression(param, body); lambda = isAnonAsync ? l.WithAsyncKeyword(asyncKeyword) : l; } return(lambda); }
public async Task <CSharpSyntaxNode> Convert(VBSyntax.LambdaExpressionSyntax vbNode, ParameterListSyntax param, IReadOnlyCollection <StatementSyntax> convertedStatements) { BlockSyntax block = null; ExpressionSyntax expressionBody = null; ArrowExpressionClauseSyntax arrow = null; if (!convertedStatements.TryUnpackSingleStatement(out StatementSyntax singleStatement)) { convertedStatements = convertedStatements.Select(l => l.WithTrailingTrivia(SyntaxFactory.ElasticCarriageReturnLineFeed)).ToList(); block = SyntaxFactory.Block(convertedStatements); } else if (singleStatement.TryUnpackSingleExpressionFromStatement(out expressionBody)) { arrow = SyntaxFactory.ArrowExpressionClause(expressionBody); } else { block = SyntaxFactory.Block(singleStatement); } var functionStatement = await ConvertToFunctionDeclarationOrNull(vbNode, param, block, arrow); if (functionStatement != null) { return(functionStatement); } var body = (CSharpSyntaxNode)block ?? expressionBody; LambdaExpressionSyntax lambda; if (param.Parameters.Count == 1 && param.Parameters.Single().Type == null) { lambda = SyntaxFactory.SimpleLambdaExpression(param.Parameters[0], body); } else { lambda = SyntaxFactory.ParenthesizedLambdaExpression(param, body); } return(lambda); }