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); }
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)); }