Beispiel #1
0
        public CSharpSyntaxNode Convert(TryStatement node)
        {
            TryStatementSyntax csTryStatement = SyntaxFactory.TryStatement().WithBlock(node.TryBlock.ToCsNode <BlockSyntax>());

            if (node.CatchClause != null)
            {
                csTryStatement = csTryStatement.AddCatches(node.CatchClause.ToCsNode <CatchClauseSyntax>());
            }
            if (node.FinallyBlock != null)
            {
                csTryStatement = csTryStatement.WithFinally(SyntaxFactory.FinallyClause(node.FinallyBlock.ToCsNode <BlockSyntax>()));
            }

            return(csTryStatement);
        }
        private static TryStatementSyntax addCatches(ConversionContext context, CatchClause ctch,
                                                     string typeName, TryStatementSyntax trySyn)
        {
            var block            = ctch.getCatchBlock();
            var catchStatements  = block.getStmts().ToList <Statement>();
            var catchConverted   = StatementVisitor.VisitStatements(context, catchStatements);
            var catchBlockSyntax = SyntaxFactory.Block(catchConverted);

            var type = TypeHelper.ConvertType(typeName);

            trySyn = trySyn.AddCatches(
                SyntaxFactory.CatchClause(
                    SyntaxFactory.CatchDeclaration(
                        SyntaxFactory.ParseTypeName(type),
                        SyntaxFactory.ParseToken(ctch.getParam().getId().toString())
                        ),
                    filter: null,
                    block: catchBlockSyntax
                    )
                );
            return(trySyn);
        }
Beispiel #3
0
        private async Task <Document> AddTryCatchAsync(CodeFixContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;
            var root     = await document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var         diagnostic     = context.Diagnostics.First();
            var         diagnosticSpan = diagnostic.Location.SourceSpan;
            SyntaxToken invocation     = root.FindToken(diagnosticSpan.Start);

            InvocationExpressionSyntax completeMethod = invocation.Parent.FirstAncestorOrSelf <InvocationExpressionSyntax>();
            var methodAttribs = completeMethod.Parent.FirstAncestorOrSelf <MethodDeclarationSyntax>().AttributeLists;

            SemanticModel sm = await document.GetSemanticModelAsync();

            var attribs = PortiaRoslynCheckedExceptionAnalyzer.GetAllAttributes(sm, completeMethod);

            var tryElement = invocation.Parent.FirstAncestorOrSelf <TryStatementSyntax>();

            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

            SyntaxNode newRoot = null;

            var catches = new List <CatchClauseSyntax>();

            foreach (var attrib in attribs)
            {
                var typeName = "";
                // I used this way because of the exception described in https://github.com/dotnet/roslyn/issues/6226
                foreach (var item in attrib.ConstructorArguments)
                {
                    typeName = item.Value.ToString();
                    break;
                }

                var attribItems = from element in methodAttribs
                                  from identifier in element.DescendantNodes().OfType <IdentifierNameSyntax>()
                                  from argument in element.DescendantNodes().OfType <AttributeArgumentSyntax>()
                                  from identifier2 in argument.DescendantNodes().OfType <IdentifierNameSyntax>()
                                  let identifierType = sm.GetTypeInfo(identifier)
                                                       let identifier2Type = sm.GetTypeInfo(identifier2)
                                                                             where identifierType.Type != null && identifierType.Type.ToString().Equals(typeof(ThrowsExceptionAttribute).FullName) &&
                                                                             identifier2Type.Type != null && identifier2Type.Type.ToString().Equals(typeName)
                                                                             select element;

                if (attribItems.Any())
                {
                    continue;
                }

                bool createCatchPart = tryElement == null;
                if (!createCatchPart)
                {
                    var exists = false;
                    foreach (var f in tryElement.Catches)
                    {
                        if (f.Declaration != null)
                        {
                            foreach (var k in f.Declaration.DescendantNodes().OfType <IdentifierNameSyntax>())
                            {
                                var typeInfo = sm.GetTypeInfo(k);
                                if (typeInfo.Type == null)
                                {
                                    continue;
                                }

                                if (typeInfo.Type.ToString().Equals(typeof(Exception).FullName) ||
                                    typeInfo.Type.ToString().Equals(typeName))
                                {
                                    exists = true;
                                    break;
                                }
                            }
                        }

                        if (exists)
                        {
                            break;
                        }
                    }

                    createCatchPart = !exists;
                }

                //if (tryElement == null || !tryElement.Catches.Any(f => f.Declaration.Type is IdentifierNameSyntax && ((IdentifierNameSyntax)f.Declaration.Type).Identifier.Text.Equals(typeName)))
                if (createCatchPart)
                {
                    IdentifierNameSyntax catchTypeSyntax = SyntaxFactory.IdentifierName(typeName);
                    var catchDeclaration = SyntaxFactory.CatchDeclaration(catchTypeSyntax, new SyntaxToken());
                    var blockSyntax      = SyntaxFactory.Block();
                    var catchPart        = SyntaxFactory.CatchClause(catchDeclaration, null, blockSyntax);

                    catches.Add(catchPart);
                }
            }

            if (tryElement != null)
            {
                newRoot = oldRoot.InsertNodesAfter(tryElement.Catches.Last(), catches);
            }
            else
            {
                ExpressionStatementSyntax body = completeMethod.FirstAncestorOrSelf <ExpressionStatementSyntax>();
                var         expressionIndex    = body.Parent.ChildNodesAndTokens().ToList().IndexOf(body);
                var         prevSyntax         = (SyntaxNode)body.Parent.ChildNodesAndTokens().ToList()[expressionIndex - 1];
                BlockSyntax block = SyntaxFactory.Block(body);


                TryStatementSyntax trySyntax = SyntaxFactory.TryStatement(block, new SyntaxList <CatchClauseSyntax>(), null);
                trySyntax = trySyntax.AddCatches(catches.ToArray());

                newRoot = oldRoot.ReplaceNode(body, trySyntax);
            }

            return(document.WithSyntaxRoot(newRoot));
        }
        private static async Task <Document> AddTryCatchAsync(CodeFixContext context, CancellationToken cancellationToken)
        {
            var document = context.Document;
            var root     = await document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var         diagnostic     = context.Diagnostics.First();
            var         diagnosticSpan = diagnostic.Location.SourceSpan;
            SyntaxToken invocation     = root.FindToken(diagnosticSpan.Start);

            InvocationExpressionSyntax completeMethod = await GetInvokedMethodAsync(context, cancellationToken);

            SemanticModel sm = await document.GetSemanticModelAsync();

            var calleeAttributes  = NotHandledAnalyzer.GetAllAttributes(sm, completeMethod);
            var catchedAttributes = await GetCallerAttributesAsync(context, cancellationToken);

            var tryElement = invocation.Parent.FirstAncestorOrSelf <TryStatementSyntax>();

            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

            SyntaxNode newRoot = null;

            var catches = new List <CatchClauseSyntax>();

            foreach (var attrib in calleeAttributes)
            {
                var skip          = false;
                var typeParameter = attrib.AttributeData.ConstructorArguments.FirstOrDefault(f => f.Type.TypeKind == TypeKind.Class);
                if (typeParameter.Type == null)
                {
                    continue;
                }

                var exceptionName = typeParameter.Value.ToString();
                foreach (var catchedAttribute in catchedAttributes)
                {
                    var typeOfExp = catchedAttribute.DescendantNodes().OfType <TypeOfExpressionSyntax>();
                    if (typeOfExp == null || !typeOfExp.Any())
                    {
                        skip = true;
                        continue;
                    }

                    var identifier = typeOfExp.First().DescendantNodes().OfType <IdentifierNameSyntax>();
                    if (identifier == null || !identifier.Any())
                    {
                        skip = true;
                        continue;
                    }

                    var semanticType = sm.GetTypeInfo(identifier.First()).Type;
                    if (semanticType != null && exceptionName.Equals(semanticType.ToString()))
                    {
                        skip = true;
                        break;
                    }
                }

                if (skip)
                {
                    continue;
                }

                bool createCatchPart = tryElement == null;
                if (!createCatchPart)
                {
                    var exists = false;
                    foreach (var f in tryElement.Catches)
                    {
                        if (f.Declaration != null)
                        {
                            foreach (var k in f.Declaration.DescendantNodes().OfType <IdentifierNameSyntax>())
                            {
                                var typeInfo = sm.GetTypeInfo(k);
                                if (typeInfo.Type == null)
                                {
                                    continue;
                                }

                                if (typeInfo.Type.ToString().Equals(typeof(Exception).FullName) ||
                                    typeInfo.Type.ToString().Equals(exceptionName))
                                {
                                    exists = true;
                                    break;
                                }
                            }
                        }

                        if (exists)
                        {
                            break;
                        }
                    }

                    createCatchPart = !exists;
                }

                if (createCatchPart)
                {
                    IdentifierNameSyntax catchTypeSyntax = SyntaxFactory.IdentifierName(exceptionName);
                    var catchDeclaration = SyntaxFactory.CatchDeclaration(catchTypeSyntax, new SyntaxToken());
                    var blockSyntax      = SyntaxFactory.Block();
                    var catchPart        = SyntaxFactory.CatchClause(catchDeclaration, null, blockSyntax);

                    catches.Add(catchPart);
                }
            }

            try
            {
                if (tryElement != null)
                {
                    newRoot = oldRoot.InsertNodesAfter(tryElement.Catches.Last(), catches);
                }
                else
                {
                    var         body            = completeMethod.FirstAncestorOrSelf <StatementSyntax>();
                    var         expressionIndex = body.Parent.ChildNodesAndTokens().ToList().IndexOf(body);
                    BlockSyntax block           = SyntaxFactory.Block(body);

                    TryStatementSyntax trySyntax = SyntaxFactory.TryStatement(block, new SyntaxList <CatchClauseSyntax>(), null);
                    trySyntax = trySyntax.AddCatches(catches.ToArray()).NormalizeWhitespace(elasticTrivia: true);

                    newRoot = oldRoot.ReplaceNode(body, trySyntax);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
            }

            return(document.WithSyntaxRoot(newRoot));
        }