private void AnalyzeSingleLineCommentTrivia(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) { return; } var root = context.Tree.GetRoot(); var comments = root.DescendantTrivia() .Where(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)) .ToArray(); for (var i = 0; i < comments.Length; i++) { var comment = comments[i]; var code = GetFullCommentedCode(root, comment); if (!CouldBeSourceCode(code.Code)) { continue; } i += code.NumberOfComments - 1; Location.Create(context.Tree, new TextSpan(code.Start, code.End)); var diagnostic = Diagnostic.Create(Rule, comment.GetLocation()); context.ReportDiagnostic(diagnostic); } }
private static void AnalyzeTree(SyntaxTreeAnalysisContext context, Compilation compilation) { if (context.IsGenerated()) return; if (!compilation.SyntaxTrees.Contains(context.Tree)) return; var semanticModel = compilation.GetSemanticModel(context.Tree); SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) return; var types = GetTypesInRoot(root); foreach (var type in types) { var fieldDeclarations = type.ChildNodes().OfType<FieldDeclarationSyntax>(); var variablesToMakeReadonly = GetCandidateVariables(semanticModel, fieldDeclarations); var typeSymbol = semanticModel.GetDeclaredSymbol(type); if (typeSymbol == null) continue; var methods = typeSymbol.GetAllMethodsIncludingFromInnerTypes(); foreach (var method in methods) { foreach (var syntaxReference in method.DeclaringSyntaxReferences) { var syntaxRefSemanticModel = syntaxReference.SyntaxTree.Equals(context.Tree) ? semanticModel : compilation.GetSemanticModel(syntaxReference.SyntaxTree); var descendants = syntaxReference.GetSyntax().DescendantNodes().ToList(); var assignments = descendants.OfKind(SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression, SyntaxKind.SubtractAssignmentExpression); foreach (AssignmentExpressionSyntax assignment in assignments) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, assignment, fieldSymbol); } var postFixUnaries = descendants.OfKind(SyntaxKind.PostIncrementExpression, SyntaxKind.PostDecrementExpression); foreach (PostfixUnaryExpressionSyntax postFixUnary in postFixUnaries) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(postFixUnary.Operand).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, postFixUnary, fieldSymbol); } var preFixUnaries = descendants.OfKind(SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); foreach (PrefixUnaryExpressionSyntax preFixUnary in preFixUnaries) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(preFixUnary.Operand).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, preFixUnary, fieldSymbol); } } } foreach (var readonlyVariable in variablesToMakeReadonly.Values) { var props = new Dictionary<string, string> { { "identifier", readonlyVariable.Identifier.Text } }.ToImmutableDictionary(); var diagnostic = Diagnostic.Create(Rule, readonlyVariable.GetLocation(), props, readonlyVariable.Identifier.Text); context.ReportDiagnostic(diagnostic); } } }
private static void AnalyzeTree(SyntaxTreeAnalysisContext context, Compilation compilation) { if (context.IsGenerated()) return; if (!compilation.SyntaxTrees.Contains(context.Tree)) return; var semanticModel = compilation.GetSemanticModel(context.Tree); SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) return; var types = GetTypesInRoot(root); foreach (var type in types) { var fieldDeclarations = type.ChildNodes().OfType<FieldDeclarationSyntax>(); var variablesToMakeReadonly = GetCandidateVariables(semanticModel, fieldDeclarations); var typeSymbol = semanticModel.GetDeclaredSymbol(type); if (typeSymbol == null) continue; var methods = typeSymbol.GetAllMethodsIncludingFromInnerTypes(); foreach (var method in methods) { foreach (var syntaxReference in method.DeclaringSyntaxReferences) { var syntaxRefSemanticModel = syntaxReference.SyntaxTree.Equals(context.Tree) ? semanticModel : compilation.GetSemanticModel(syntaxReference.SyntaxTree); var assignments = syntaxReference.GetSyntax().DescendantNodes().OfType<AssignmentExpressionSyntax>(); foreach (var assignment in assignments) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol; if (fieldSymbol == null) continue; if (method.MethodKind == MethodKind.StaticConstructor && fieldSymbol.IsStatic) AddVariableThatWasSkippedBeforeBecauseItLackedAInitializer(variablesToMakeReadonly, fieldSymbol, assignment); else if (method.MethodKind == MethodKind.Constructor && !fieldSymbol.IsStatic) AddVariableThatWasSkippedBeforeBecauseItLackedAInitializer(variablesToMakeReadonly, fieldSymbol, assignment); else RemoveVariableThatHasAssignment(variablesToMakeReadonly, fieldSymbol); } } } foreach (var readonlyVariable in variablesToMakeReadonly.Values) { var props = new Dictionary<string, string> { { "identifier", readonlyVariable.Identifier.Text } }.ToImmutableDictionary(); var diagnostic = Diagnostic.Create(Rule, readonlyVariable.GetLocation(), props, readonlyVariable.Identifier.Text); context.ReportDiagnostic(diagnostic); } } }
private static void AnalyzeTrailingTrivia(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) return; SourceText text; if (!context.Tree.TryGetText(out text)) return; SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) return; foreach (var line in text.Lines) { if (line.End == 0) continue; var endSpan = TextSpan.FromBounds(line.End - 1, line.End); var candidateWhiteSpace = line.Text.GetSubText(endSpan).ToString(); if (string.Compare(candidateWhiteSpace, "\n", StringComparison.Ordinal) == 0 || !Regex.IsMatch(candidateWhiteSpace, @"\s")) continue; var isLiteral = root.FindNode(endSpan) is LiteralExpressionSyntax; if (isLiteral) return; var diag = Diagnostic.Create(Rule, Location.Create(context.Tree, line.Span)); context.ReportDiagnostic(diag); } }
private static void AnalyzeTrailingTrivia(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) { return; } SourceText text; if (!context.Tree.TryGetText(out text)) { return; } SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) { return; } foreach (var line in text.Lines) { if (line.End == 0) { continue; } var endSpan = TextSpan.FromBounds(line.End - 1, line.End); var candidateWhiteSpace = line.Text.GetSubText(endSpan).ToString(); if (string.Compare(candidateWhiteSpace, "\n", StringComparison.Ordinal) == 0 || !Regex.IsMatch(candidateWhiteSpace, @"\s")) { continue; } var isLiteral = root.FindNode(endSpan) is LiteralExpressionSyntax; if (isLiteral) { return; } var diag = Diagnostic.Create(Rule, Location.Create(context.Tree, line.Span)); context.ReportDiagnostic(diag); } }
private void analyzeTree(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) { return; } var tree = context.Tree; if (ignoreTree(tree)) { return; } var root = tree.GetRoot(); var comments = root.DescendantTrivia().Where(t => t.Kind() == SyntaxKind.SingleLineCommentTrivia); foreach (var commentNode in comments) { // Checking whitespacing is not the responsibility of this analyzer. var text = commentNode.GetCommentContent().Trim(); if (string.IsNullOrEmpty(text)) { continue; } if (ignoreComment(text)) { continue; } if (char.IsLower(text[0])) { context.ReportDiagnostic(Diagnostic.Create(rule_StartsWithUpper, commentNode.GetLocation(), text)); } } }
private void AnalyzeUsings(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) { return; } var root = context.Tree.GetRoot() as CompilationUnitSyntax; if (root == null) { return; } var reqUsings = new HashSet <string> { "System", "System.Collections.Generic", "System.Linq" }; foreach (var item in root.Usings) { reqUsings.Remove(item.Name.ToString()); if (reqUsings.Count == 0) { return; } } var message = string.Join(Environment.NewLine, reqUsings); var location = root.Usings.Count == 0 ? root.GetLocation() : root.Usings[0].GetLocation(); var diagnostic = Diagnostic.Create(Rule, location, message); context.ReportDiagnostic(diagnostic); }
private void AnalyzeSingleLineCommentTrivia(SyntaxTreeAnalysisContext context) { if (context.IsGenerated()) return; var root = context.Tree.GetRoot(); var comments = root.DescendantTrivia() .Where(trivia => trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)) .ToArray(); for (var i = 0; i < comments.Length; i++) { var comment = comments[i]; var code = GetFullCommentedCode(root, comment); if (!CouldBeSourceCode(code.Code)) continue; i += code.NumberOfComments - 1; Location.Create(context.Tree, new TextSpan(code.Start, code.End)); var diagnostic = Diagnostic.Create(Rule, comment.GetLocation()); context.ReportDiagnostic(diagnostic); } }
private static void AnalyzeTree(SyntaxTreeAnalysisContext context, Compilation compilation) { if (context.IsGenerated()) { return; } if (!compilation.SyntaxTrees.Contains(context.Tree)) { return; } var semanticModel = compilation.GetSemanticModel(context.Tree); SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) { return; } var types = GetTypesInRoot(root); foreach (var type in types) { var fieldDeclarations = type.ChildNodes().OfType <FieldDeclarationSyntax>(); var variablesToMakeReadonly = GetCandidateVariables(semanticModel, fieldDeclarations); var typeSymbol = semanticModel.GetDeclaredSymbol(type); if (typeSymbol == null) { continue; } var methods = typeSymbol.GetAllMethodsIncludingFromInnerTypes(); foreach (var method in methods) { foreach (var syntaxReference in method.DeclaringSyntaxReferences) { var syntaxRefSemanticModel = syntaxReference.SyntaxTree.Equals(context.Tree) ? semanticModel : compilation.GetSemanticModel(syntaxReference.SyntaxTree); var descendants = syntaxReference.GetSyntax().DescendantNodes().ToList(); var assignments = descendants.OfKind(SyntaxKind.SimpleAssignmentExpression, SyntaxKind.AddAssignmentExpression, SyntaxKind.AndAssignmentExpression, SyntaxKind.DivideAssignmentExpression, SyntaxKind.ExclusiveOrAssignmentExpression, SyntaxKind.LeftShiftAssignmentExpression, SyntaxKind.ModuloAssignmentExpression, SyntaxKind.MultiplyAssignmentExpression, SyntaxKind.OrAssignmentExpression, SyntaxKind.RightShiftAssignmentExpression, SyntaxKind.SubtractAssignmentExpression); foreach (AssignmentExpressionSyntax assignment in assignments) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, assignment, fieldSymbol); } var postFixUnaries = descendants.OfKind(SyntaxKind.PostIncrementExpression, SyntaxKind.PostDecrementExpression); foreach (PostfixUnaryExpressionSyntax postFixUnary in postFixUnaries) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(postFixUnary.Operand).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, postFixUnary, fieldSymbol); } var preFixUnaries = descendants.OfKind(SyntaxKind.PreDecrementExpression, SyntaxKind.PreIncrementExpression); foreach (PrefixUnaryExpressionSyntax preFixUnary in preFixUnaries) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(preFixUnary.Operand).Symbol as IFieldSymbol; VerifyVariable(variablesToMakeReadonly, method, syntaxRefSemanticModel, preFixUnary, fieldSymbol); } } } foreach (var readonlyVariable in variablesToMakeReadonly.Values) { var props = new Dictionary <string, string> { { "identifier", readonlyVariable.Identifier.Text } }.ToImmutableDictionary(); var diagnostic = Diagnostic.Create(Rule, readonlyVariable.GetLocation(), props, readonlyVariable.Identifier.Text); context.ReportDiagnostic(diagnostic); } } }
private static void AnalyzeTree(SyntaxTreeAnalysisContext context, Compilation compilation) { if (context.IsGenerated()) { return; } if (!compilation.SyntaxTrees.Contains(context.Tree)) { return; } var semanticModel = compilation.GetSemanticModel(context.Tree); SyntaxNode root; if (!context.Tree.TryGetRoot(out root)) { return; } var types = GetTypesInRoot(root); foreach (var type in types) { var fieldDeclarations = type.ChildNodes().OfType <FieldDeclarationSyntax>(); var variablesToMakeReadonly = GetCandidateVariables(semanticModel, fieldDeclarations); var typeSymbol = semanticModel.GetDeclaredSymbol(type); if (typeSymbol == null) { continue; } var methods = typeSymbol.GetAllMethodsIncludingFromInnerTypes(); foreach (var method in methods) { foreach (var syntaxReference in method.DeclaringSyntaxReferences) { var syntaxRefSemanticModel = syntaxReference.SyntaxTree.Equals(context.Tree) ? semanticModel : compilation.GetSemanticModel(syntaxReference.SyntaxTree); var assignments = syntaxReference.GetSyntax().DescendantNodes().OfType <AssignmentExpressionSyntax>(); foreach (var assignment in assignments) { var fieldSymbol = syntaxRefSemanticModel.GetSymbolInfo(assignment.Left).Symbol as IFieldSymbol; if (fieldSymbol == null) { continue; } if (method.MethodKind == MethodKind.StaticConstructor && fieldSymbol.IsStatic) { AddVariableThatWasSkippedBeforeBecauseItLackedAInitializer(variablesToMakeReadonly, fieldSymbol); } else if (method.MethodKind == MethodKind.Constructor && !fieldSymbol.IsStatic) { AddVariableThatWasSkippedBeforeBecauseItLackedAInitializer(variablesToMakeReadonly, fieldSymbol); } else { RemoveVariableThatHasAssignment(variablesToMakeReadonly, fieldSymbol); } } } } foreach (var readonlyVariable in variablesToMakeReadonly.Values) { var props = new Dictionary <string, string> { { "identifier", readonlyVariable.Identifier.Text } }.ToImmutableDictionary(); var diagnostic = Diagnostic.Create(Rule, readonlyVariable.GetLocation(), props, readonlyVariable.Identifier.Text); context.ReportDiagnostic(diagnostic); } } }