private static AddExceptionToDocumentationCommentAnalysis Analyze( SyntaxNode node, ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken) { var exceptionSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken) as INamedTypeSymbol; if (exceptionSymbol?.InheritsFromException(semanticModel) == true) { ISymbol declarationSymbol = GetDeclarationSymbol(node.SpanStart, semanticModel, cancellationToken); if (declarationSymbol?.GetSyntax(cancellationToken) is MemberDeclarationSyntax containingMember) { DocumentationCommentTriviaSyntax comment = containingMember.GetSingleLineDocumentationComment(); if (comment != null && CanAddExceptionToComment(comment, exceptionSymbol, semanticModel, cancellationToken)) { ThrowInfo throwInfo = ThrowInfo.Create(node, exceptionSymbol, declarationSymbol); return(new AddExceptionToDocumentationCommentAnalysis(throwInfo, comment.ParentTrivia)); } } } return(AddExceptionToDocumentationCommentAnalysis.NoSuccess); }
private static ThrowInfo GetUndocumentedExceptionInfo( SyntaxNode node, ExpressionSyntax expression, MemberDeclarationSyntax declaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (expression != null) { var typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken) as INamedTypeSymbol; if (typeSymbol?.InheritsFromException(semanticModel) == true) { DocumentationCommentTriviaSyntax comment = declaration.GetSingleLineDocumentationComment(); if (comment != null && CanAddExceptionToComment(comment, typeSymbol, semanticModel, cancellationToken)) { return(ThrowInfo.Create(node, typeSymbol, declarationSymbol)); } } } return(null); }
private static async Task <Document> RefactorAsync( Document document, SyntaxNode node, ExpressionSyntax expression, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); ITypeSymbol exceptionSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); ISymbol declarationSymbol = GetDeclarationSymbol(node.SpanStart, semanticModel, cancellationToken); var memberDeclaration = await declarationSymbol .DeclaringSyntaxReferences[0] .GetSyntaxAsync(cancellationToken) .ConfigureAwait(false) as MemberDeclarationSyntax; SyntaxTrivia trivia = memberDeclaration.GetSingleLineDocumentationCommentTrivia(); ThrowInfo throwInfo = ThrowInfo.Create(node, exceptionSymbol, declarationSymbol); return(await RefactorAsync( document, trivia, throwInfo, memberDeclaration, declarationSymbol, semanticModel, cancellationToken).ConfigureAwait(false)); }
private static ThrowInfo GetUndocumentedExceptionInfo( SyntaxNode node, ExpressionSyntax expression, MemberDeclarationSyntax declaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (expression != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (typeSymbol?.IsErrorType() == false && SymbolUtility.IsException(typeSymbol, semanticModel)) { DocumentationCommentTriviaSyntax comment = declaration.GetSingleLineDocumentationComment(); if (comment != null && !ContainsException(comment, typeSymbol, semanticModel, cancellationToken)) { return(ThrowInfo.Create(node, typeSymbol, declarationSymbol)); } } } return(null); }
private static ThrowInfo GetUndocumentedExceptionInfo( SyntaxNode node, ExpressionSyntax expression, MemberDeclarationSyntax containingMember, SemanticModel semanticModel, CancellationToken cancellationToken) { if (expression != null) { ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (typeSymbol?.IsErrorType() == false && Symbol.IsException(typeSymbol, semanticModel)) { SyntaxTrivia trivia = containingMember.GetSingleLineDocumentationComment(); if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)) { var comment = trivia.GetStructure() as DocumentationCommentTriviaSyntax; if (comment?.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) == true && !ContainsException(comment, typeSymbol, semanticModel, cancellationToken)) { return(ThrowInfo.Create(node, typeSymbol)); } } } } return(null); }
private static async Task ComputeRefactoringAsync(RefactoringContext context, SyntaxNode node, ExpressionSyntax expression) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol exceptionSymbol = semanticModel.GetTypeSymbol(expression, context.CancellationToken); if (exceptionSymbol?.IsErrorType() == false && Symbol.IsException(exceptionSymbol, semanticModel)) { ISymbol declarationSymbol = GetDeclarationSymbol(node.SpanStart, semanticModel, context.CancellationToken); if (declarationSymbol != null) { var containingMember = await declarationSymbol .DeclaringSyntaxReferences[0] .GetSyntaxAsync(context.CancellationToken) .ConfigureAwait(false) as MemberDeclarationSyntax; if (containingMember != null) { SyntaxTrivia trivia = containingMember.GetSingleLineDocumentationComment(); if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)) { var comment = trivia.GetStructure() as DocumentationCommentTriviaSyntax; if (comment?.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) == true && !ContainsException(comment, exceptionSymbol, semanticModel, context.CancellationToken)) { ThrowInfo throwInfo1 = ThrowInfo.Create(node, exceptionSymbol); IParameterSymbol parameterSymbol = throwInfo1.GetParameterSymbol(declarationSymbol, semanticModel, context.CancellationToken); context.RegisterRefactoring( "Add exception to documentation comment", cancellationToken => RefactorAsync(context.Document, trivia, exceptionSymbol, parameterSymbol, cancellationToken)); foreach (ThrowInfo throwInfo2 in GetOtherUndocumentedExceptions(containingMember, f => node != f, semanticModel, context.CancellationToken)) { if (throwInfo2.ExceptionSymbol != exceptionSymbol) { var infos = new List <ThrowInfo>(); infos.Add(throwInfo1); infos.Add(throwInfo2); context.RegisterRefactoring( "Add all exceptions to documentation comment", cancellationToken => RefactorAsync(context.Document, infos, containingMember, declarationSymbol, trivia, cancellationToken)); break; } } } } } } } }
private static IEnumerable <ThrowInfo> GetOtherUndocumentedExceptions( MemberDeclarationSyntax declaration, ISymbol declarationSymbol, Func <SyntaxNode, bool> predicate, SemanticModel semanticModel, CancellationToken cancellationToken) { foreach (SyntaxNode node in declaration.DescendantNodes(f => !f.IsKind( SyntaxKind.AnonymousMethodExpression, SyntaxKind.SimpleLambdaExpression, SyntaxKind.ParenthesizedLambdaExpression))) { switch (node.Kind()) { case SyntaxKind.ThrowStatement: { if (predicate(node)) { var throwStatement = (ThrowStatementSyntax)node; ThrowInfo info = GetUndocumentedExceptionInfo(node, throwStatement.Expression, declaration, declarationSymbol, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } case SyntaxKind.ThrowExpression: { if (predicate(node)) { var throwExpression = (ThrowExpressionSyntax)node; ThrowInfo info = GetUndocumentedExceptionInfo(node, throwExpression.Expression, declaration, declarationSymbol, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } } } }
private static IEnumerable <ThrowInfo> GetOtherUndocumentedExceptions( MemberDeclarationSyntax declaration, ISymbol declarationSymbol, Func <SyntaxNode, bool> predicate, INamedTypeSymbol exceptionSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { foreach (SyntaxNode node in declaration.DescendantNodes(f => !CSharpFacts.IsAnonymousFunctionExpression(f.Kind()))) { switch (node.Kind()) { case SyntaxKind.ThrowStatement: { if (predicate(node)) { var throwStatement = (ThrowStatementSyntax)node; ThrowInfo info = GetUndocumentedExceptionInfo(node, throwStatement.Expression, declaration, declarationSymbol, exceptionSymbol, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } case SyntaxKind.ThrowExpression: { if (predicate(node)) { var throwExpression = (ThrowExpressionSyntax)node; ThrowInfo info = GetUndocumentedExceptionInfo(node, throwExpression.Expression, declaration, declarationSymbol, exceptionSymbol, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } } } }
private static async Task <Document> RefactorAsync( Document document, SyntaxTrivia trivia, ThrowInfo throwInfo, MemberDeclarationSyntax memberDeclaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var throwInfos = new List <ThrowInfo>() { throwInfo }; INamedTypeSymbol exceptionSymbol = semanticModel.GetTypeByMetadataName("System.Exception"); foreach (ThrowInfo info in GetOtherUndocumentedExceptions(memberDeclaration, declarationSymbol, node => node != throwInfo.Node, exceptionSymbol, semanticModel, cancellationToken)) { if (!throwInfos.Any(f => f.ExceptionSymbol == info.ExceptionSymbol)) { throwInfos.Add(info); } } string indent = GetIndent(memberDeclaration.GetLeadingTrivia()); StringBuilder sb = StringBuilderCache.GetInstance(); foreach (ThrowInfo info in throwInfos) { sb.Append(indent); IParameterSymbol parameterSymbol = info.GetParameterSymbol(semanticModel, cancellationToken); AppendExceptionDocumentation(trivia, info.ExceptionSymbol, parameterSymbol, semanticModel, ref sb); } string newText = StringBuilderCache.GetStringAndFree(sb); var textChange = new TextChange(new TextSpan(trivia.FullSpan.End, 0), newText); SourceText newSourceText = sourceText.WithChanges(textChange); return(document.WithText(newSourceText)); }
private static IEnumerable <ThrowInfo> GetOtherUndocumentedExceptions( MemberDeclarationSyntax containingMember, Func <SyntaxNode, bool> predicate, SemanticModel semanticModel, CancellationToken cancellationToken) { foreach (SyntaxNode descendant in containingMember.DescendantNodes()) { switch (descendant.Kind()) { case SyntaxKind.ThrowStatement: { if (predicate(descendant)) { var throwStatement = (ThrowStatementSyntax)descendant; ThrowInfo info = GetUndocumentedExceptionInfo(descendant, throwStatement.Expression, containingMember, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } case SyntaxKind.ThrowExpression: { if (predicate(descendant)) { var throwExpression = (ThrowExpressionSyntax)descendant; ThrowInfo info = GetUndocumentedExceptionInfo(descendant, throwExpression.Expression, containingMember, semanticModel, cancellationToken); if (info != null) { yield return(info); } } break; } } } }
private static Task <Document> RefactorAsync( Document document, SyntaxTrivia trivia, ThrowInfo throwInfo, MemberDeclarationSyntax memberDeclaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { var throwInfos = new List <ThrowInfo>() { throwInfo }; INamedTypeSymbol exceptionSymbol = semanticModel.GetTypeByMetadataName("System.Exception"); foreach (ThrowInfo info in GetOtherUndocumentedExceptions(memberDeclaration, declarationSymbol, node => node != throwInfo.Node, exceptionSymbol, semanticModel, cancellationToken)) { if (!throwInfos.Any(f => SymbolEqualityComparer.Default.Equals(f.ExceptionSymbol, info.ExceptionSymbol))) { throwInfos.Add(info); } } string indent = GetIndent(memberDeclaration.GetLeadingTrivia()); StringBuilder sb = StringBuilderCache.GetInstance(); foreach (ThrowInfo info in throwInfos) { sb.Append(indent); IParameterSymbol parameterSymbol = info.GetParameterSymbol(semanticModel, cancellationToken); AppendExceptionDocumentation(trivia, info.ExceptionSymbol, parameterSymbol, semanticModel, ref sb); } return(document.WithTextChangeAsync( new TextSpan(trivia.FullSpan.End, 0), StringBuilderCache.GetStringAndFree(sb), cancellationToken)); }
private static async Task <Document> RefactorAsync( Document document, SyntaxTrivia trivia, ThrowInfo throwInfo, MemberDeclarationSyntax memberDeclaration, ISymbol declarationSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var throwInfos = new List <ThrowInfo>(); throwInfos.Add(throwInfo); foreach (ThrowInfo info in GetOtherUndocumentedExceptions(memberDeclaration, declarationSymbol, node => node != throwInfo.Node, semanticModel, cancellationToken)) { if (!throwInfos.Any(f => f.ExceptionSymbol == info.ExceptionSymbol)) { throwInfos.Add(info); } } string indent = GetIndent(trivia, sourceText, cancellationToken); var sb = new StringBuilder(); foreach (ThrowInfo info in throwInfos) { sb.Append(indent); IParameterSymbol parameterSymbol = info.GetParameterSymbol(semanticModel, cancellationToken); AppendExceptionDocumentation(trivia, info.ExceptionSymbol, parameterSymbol, semanticModel, ref sb); } var textChange = new TextChange(new TextSpan(trivia.FullSpan.End, 0), sb.ToString()); SourceText newSourceText = sourceText.WithChanges(textChange); return(document.WithText(newSourceText)); }
private static AddExceptionToDocumentationCommentAnalysis Analyze( SyntaxNode node, ExpressionSyntax expression, SemanticModel semanticModel, CancellationToken cancellationToken) { ITypeSymbol exceptionSymbol = semanticModel.GetTypeSymbol(expression, cancellationToken); if (exceptionSymbol?.IsErrorType() == false && SymbolUtility.IsException(exceptionSymbol, semanticModel)) { ISymbol declarationSymbol = GetDeclarationSymbol(node.SpanStart, semanticModel, cancellationToken); if (declarationSymbol != null) { var containingMember = declarationSymbol .DeclaringSyntaxReferences[0] .GetSyntax(cancellationToken) as MemberDeclarationSyntax; if (containingMember != null) { SyntaxTrivia trivia = containingMember.GetSingleLineDocumentationComment(); if (trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)) { var comment = trivia.GetStructure() as DocumentationCommentTriviaSyntax; if (comment?.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) == true && !ContainsException(comment, exceptionSymbol, semanticModel, cancellationToken)) { ThrowInfo throwInfo = ThrowInfo.Create(node, exceptionSymbol, declarationSymbol); return(new AddExceptionToDocumentationCommentAnalysis(throwInfo, trivia)); } } } } } return(AddExceptionToDocumentationCommentAnalysis.NoSuccess); }
private static ThrowInfo GetUndocumentedExceptionInfo( SyntaxNode node, ExpressionSyntax expression, MemberDeclarationSyntax declaration, ISymbol declarationSymbol, INamedTypeSymbol exceptionSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { if (expression == null) { return(null); } if (semanticModel.GetTypeSymbol(expression, cancellationToken) is not INamedTypeSymbol typeSymbol) { return(null); } if (!InheritsFromException(typeSymbol, exceptionSymbol)) { return(null); } DocumentationCommentTriviaSyntax comment = declaration.GetSingleLineDocumentationComment(); if (comment == null) { return(null); } if (!CanAddExceptionToComment(comment, typeSymbol, semanticModel, cancellationToken)) { return(null); } return(ThrowInfo.Create(node, typeSymbol, declarationSymbol)); }
public IParameterSymbol GetParameterSymbol( SemanticModel semanticModel, CancellationToken cancellationToken) { return(ThrowInfo?.GetParameterSymbol(semanticModel, cancellationToken)); }
internal AddExceptionToDocumentationCommentAnalysis(ThrowInfo info, SyntaxTrivia documentationComment) { ThrowInfo = info; DocumentationComment = documentationComment; }