Пример #1
0
        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);
            }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }