Пример #1
0
 public void AddCommentTrivia(SyntaxTrivia trivia,
                              LocationStore commentLocationstore, ClassStore classStore, string fileName)
 {
     if (trivia.Kind() == SyntaxKind.SingleLineCommentTrivia)
     {
         Comment comment = new SingleLineComment(trivia.ToString(),
                                                 trivia.GetLocation().GetLineSpan().EndLinePosition.Line + 1)
         {
             FileName = fileName,
         };
         comment.Initialize(commentLocationstore, classStore);
         Comments.Add(comment);
     }
     else if (trivia.Kind() == SyntaxKind.MultiLineCommentTrivia)
     {
         Comment comment = new MultiLineComment(trivia.ToString(),
                                                trivia.GetLocation().GetLineSpan().StartLinePosition.Line + 1,
                                                trivia.GetLocation().GetLineSpan().EndLinePosition.Line + 1)
         {
             FileName = fileName,
         };
         comment.Initialize(commentLocationstore, classStore);
         Comments.Add(comment);
     }
 }
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.Span.Length <= 1)
            {
                return;
            }

            if (trivia.GetLocation()?.GetMappedLineSpan().StartLinePosition.Character == 0)
            {
                return;
            }

            // Code must not contain multiple whitespace characters in a row.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #3
0
        private static void ReportDiagnostic(SyntaxNodeAnalysisContext context, SyntaxToken token, SyntaxTrivia tokenLeadingTrivia, string indentation, string expectedIndentation)
        {
            Location location = (indentation.Length == 0) ? token.GetLocation() : tokenLeadingTrivia.GetLocation();
            ImmutableDictionary <string, string> properties = ImmutableDictionary.Create <string, string>().SetItem(ExpectedIndentationKey, expectedIndentation);

            context.ReportDiagnostic(Diagnostic.Create(Descriptor, location, properties));
        }
        private void HandleSingleLineCommentTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            string text = trivia.ToFullString();

            if (text.Equals("//"))
            {
                return;
            }

            // special case: commented code
            if (text.StartsWith("////"))
            {
                return;
            }

            int spaceCount = 0;

            for (int i = 2; (i < text.Length) && (text[i] == ' '); i++)
            {
                spaceCount++;
            }

            if (spaceCount == 1)
            {
                return;
            }

            // Single line comment must begin with a space.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #5
0
            public override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
            {
                if (!trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) && !trivia.IsKind(SyntaxKind.MultiLineCommentTrivia))
                {
                    return(trivia);
                }

                var lineSpan = trivia.GetLocation().GetLineSpan();

                while (lineCount < lineSpan.StartLinePosition.Line)
                {
                    allComments.AppendLine();
                    lineCount++;
                }
                string comment = trivia.ToString();

                if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia))
                {
                    comment = comment.Substring(2);
                }
                else if (trivia.IsKind(SyntaxKind.MultiLineCommentTrivia))
                {
                    comment = comment.Substring(2, comment.Length - 4);
                }

                allComments.Append(comment);
                lineCount = lineSpan.EndLinePosition.Line;

                return(trivia);
            }
Пример #6
0
 static int GetLine(SyntaxTrivia trivia)
 {
     return(trivia.GetLocation()
            .GetLineSpan()
            .StartLinePosition
            .Line);
 }
Пример #7
0
        public EvaluationResult Evaluate(SyntaxTrivia node)
        {
            var result = EvaluateImpl(node);

            if (result != null)
            {
                var sourceTree     = node.GetLocation().SourceTree;
                var filePath       = sourceTree.FilePath;
                var typeDefinition = GetNodeType(node.Token.Parent);
                var unitNamespace  = GetNamespace(node.Token.Parent);
                if (result.ErrorCount == 0)
                {
                    result.ErrorCount = 1;
                }

                result.LinesOfCodeAffected = 0;
                result.Namespace           = unitNamespace;
                result.TypeKind            = typeDefinition.Item1;
                result.TypeName            = typeDefinition.Item2;
                result.Title            = Title;
                result.Suggestion       = Suggestion;
                result.Quality          = Quality;
                result.QualityAttribute = QualityAttribute;
                result.ImpactLevel      = ImpactLevel;
                result.FilePath         = filePath;
            }

            return(result);
        }
Пример #8
0
        private static void HandleSingleLineComment(SyntaxTreeAnalysisContext context, SyntaxTrivia singleLineComment)
        {
            int index = 0;

            // PERF: Explicitly cast to IReadOnlyList so we only box once.
            IReadOnlyList <SyntaxTrivia> list = TriviaHelper.GetContainingTriviaList(singleLineComment, out index);
            var firstNonWhiteSpace            = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(list);

            // When we encounter a block of single line comments, we only want to raise this diagnostic
            // on the first or last line.  This ensures that whitespace in code commented out using
            // the Comment Selection option in Visual Studio will not raise the diagnostic for every
            // blank line in the code which is commented out.
            bool isFirst = index == firstNonWhiteSpace;

            if (!isFirst)
            {
                // This is -2 because we need to go back past the end of line trivia as well.
                var lastNonWhiteSpace = TriviaHelper.IndexOfTrailingWhitespace(list) - 2;
                if (index != lastNonWhiteSpace)
                {
                    return;
                }
            }

            if (IsNullOrWhiteSpace(singleLineComment.ToString(), 2))
            {
                var diagnostic = Diagnostic.Create(Descriptor, singleLineComment.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
        internal static GetFullCommentedCodeResult GetFullCommentedCode(SyntaxNode root, SyntaxTrivia firstComment)
        {
            var result           = new StringBuilder();
            var current          = firstComment;
            var numberOfComments = 1;
            var start            = firstComment.GetLocation().SourceSpan.Start;
            int end;

            do
            {
                end = current.GetLocation().SourceSpan.End;
                result.Append(current.ToString().Substring(2));

                var eol = root.FindTrivia(current.GetLocation().SourceSpan.End + 1);
                if (!eol.IsKind(SyntaxKind.EndOfLineTrivia))
                {
                    break;
                }

                var whitespace = root.FindTrivia(eol.GetLocation().SourceSpan.End + 1);
                if (!whitespace.IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    break;
                }

                current = root.FindTrivia(whitespace.GetLocation().SourceSpan.End + 1);
                if (!current.IsKind(SyntaxKind.SingleLineCommentTrivia))
                {
                    break;
                }

                numberOfComments++;
            } while (true);
            return(new GetFullCommentedCodeResult(result.ToString(), numberOfComments, start, end));
        }
Пример #10
0
            SyntaxTrivia ReplaceTrivia(SyntaxTrivia triv)
            {
                if (!triv.IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    return(triv);
                }
                //return triv;
                var loc = triv.GetLocation();
                var ls  = loc.GetLineSpan();

                if (ls.StartLinePosition.Character != 0)
                {
                    return(triv);
                }

                var triviaString = triv.ToFullString();

                if (triviaString.Equals(_tabs) || triviaString.Equals(_spaces))
                {
                    return(triv.CopyAnnotationsTo(SyntaxFactory.Whitespace("")));
                }

                if (triviaString.StartsWith(_tabs))
                {
                    return(triv.CopyAnnotationsTo(SyntaxFactory.Whitespace(triviaString.Substring(_tabs.Length))));
                }

                if (triviaString.StartsWith(_spaces))
                {
                    return(triv.CopyAnnotationsTo(SyntaxFactory.Whitespace(triviaString.Substring(_spaces.Length))));
                }

                return(triv);
            }
Пример #11
0
 public override void VisitTrivia(SyntaxTrivia trivia)
 {
     base.VisitTrivia(trivia);
     if (trivia.IsKind(SyntaxKind.RegionDirectiveTrivia))
     {
         regionStack.Push(trivia);
     }
     else if (trivia.IsKind(SyntaxKind.EndRegionDirectiveTrivia))
     {
         if (regionStack.Count == 0)
         {
             return;
         }
         var regionStart = regionStack.Pop();
         try {
             var first = regionStart.GetLocation().GetLineSpan();
             var last  = trivia.GetLocation().GetLineSpan();
             var v     = regionStart.ToString();
             v = v.Substring("#region".Length).Trim();
             if (v.Length == 0)
             {
                 v = "...";
             }
             Foldings.Add(new FoldingRegion(v, new DocumentRegion(first.StartLinePosition, last.EndLinePosition), FoldType.UserRegion, true));
         } catch (ArgumentOutOfRangeException) { }
     }
 }
Пример #12
0
		public EvaluationResult Evaluate(SyntaxTrivia node)
		{
			var result = EvaluateImpl(node);
			if (result != null)
			{
				var sourceTree = node.GetLocation().SourceTree;
				var filePath = sourceTree.FilePath;
				var typeDefinition = GetNodeType(node.Token.Parent);
				var unitNamespace = GetNamespace(node.Token.Parent);
				if (result.ErrorCount == 0)
				{
					result.ErrorCount = 1;
				}

				result.LinesOfCodeAffected = 0;
				result.Namespace = unitNamespace;
				result.TypeKind = typeDefinition.Item1;
				result.TypeName = typeDefinition.Item2;
				result.Title = Title;
				result.Suggestion = Suggestion;
				result.Quality = Quality;
				result.QualityAttribute = QualityAttribute;
				result.ImpactLevel = ImpactLevel;
				result.FilePath = filePath;
			}

			return result;
		}
Пример #13
0
 public override SyntaxTrivia VisitTrivia(SyntaxTrivia trivia)
 {
     if (trivia.IsKind(SyntaxKind.NullableDirectiveTrivia))
     {
         reporter.ReportDiagnostic(
             DiagnosticDescriptors.EMBED0008_NullableDirective(trivia.GetLocation()));
     }
     return(SyntaxFactory.ElasticMarker);
 }
 public static void ReportDiagnostic(
     this SyntaxTreeAnalysisContext context,
     DiagnosticDescriptor descriptor,
     SyntaxTrivia trivia,
     params object[] messageArgs)
 {
     context.ReportDiagnostic(
         Diagnostic.Create(descriptor, trivia.GetLocation(), messageArgs));
 }
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.ToFullString().IndexOf('\t') < 0)
            {
                return;
            }

            // Tabs must not be used.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.ToFullString().IndexOf('\t') < 0)
            {
                return;
            }

            // Tabs must not be used.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #17
0
 public static void ReportDiagnostic(
     SymbolAnalysisContext context,
     DiagnosticDescriptor descriptor,
     SyntaxTrivia trivia,
     params object[] messageArgs)
 {
     ReportDiagnostic(
         context: context,
         descriptor: descriptor,
         location: trivia.GetLocation(),
         messageArgs: messageArgs);
 }
Пример #18
0
        private void HandleRegionDirectiveTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            BlockSyntax blockSyntax = trivia.Token.Parent.AncestorsAndSelf().OfType <BlockSyntax>().FirstOrDefault();

            if (blockSyntax == null)
            {
                return;
            }

            // Region must not be located within a code element.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.Span.Length <= 1)
            {
                return;
            }

            if (trivia.GetLocation()?.GetMappedLineSpan().StartLinePosition.Character == 0)
            {
                return;
            }

            SyntaxToken token = trivia.Token;
            SyntaxToken precedingToken;
            SyntaxToken followingToken;

            if (token.LeadingTrivia.Contains(trivia))
            {
                precedingToken = token.GetPreviousToken();
                followingToken = token;
            }
            else if (token.TrailingTrivia.Contains(trivia))
            {
                precedingToken = token;
                followingToken = precedingToken.GetNextToken();
            }
            else
            {
                // shouldn't be reachable, but either way can't proceed
                return;
            }

            if (precedingToken.IsKind(SyntaxKind.CommaToken) || precedingToken.IsKind(SyntaxKind.SemicolonToken))
            {
                return;
            }

            // Code must not contain multiple whitespace characters in a row.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
        private void HandleSingleLineCommentTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia, bool isFirstSingleLineTrivia)
        {
            string text = trivia.ToFullString();

            if (text.Equals(@"//"))
            {
                return;
            }

            // special case: commented code
            if (text.StartsWith(@"////", StringComparison.Ordinal))
            {
                return;
            }

            // Special case: multiple dashes at start of comment
            if (text.StartsWith(@"//--", StringComparison.Ordinal))
            {
                return;
            }

            // Special case: //\ negates spacing requirements
            if (text.StartsWith(@"//\", StringComparison.Ordinal))
            {
                return;
            }

            // No need to handle documentation comments ("///") because they're not
            // reported as SingleLineCommentTrivia.

            int spaceCount = 0;

            for (int i = 2; (i < text.Length) && (text[i] == ' '); i++)
            {
                spaceCount++;
            }

            if (spaceCount == 1)
            {
                return;
            }

            // Special case: follow-on comment lines may be indented with more than
            // one space.
            if (spaceCount > 1 && !isFirstSingleLineTrivia)
            {
                return;
            }

            // Single line comment must begin with a space.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #21
0
        private static void HandleMultiLineComment(SyntaxTreeAnalysisContext context, SyntaxTrivia multiLineComment)
        {
            var nodeText = multiLineComment.ToString();

            // We remove the /* and the */ and determine if the comment has any content.
            var commentText = nodeText.Substring(2, nodeText.Length - 4);

            if (string.IsNullOrWhiteSpace(commentText))
            {
                var diagnostic = Diagnostic.Create(Descriptor, multiLineComment.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
Пример #22
0
        private static void CheckMultilineComment(SyntaxTreeAnalysisContext c, SyntaxTrivia comment)
        {
            var triviaContent = GetTriviaContent(comment);
            var triviaLines   = triviaContent.Split(MetricsBase.LineTerminators, StringSplitOptions.None);

            for (var triviaLineNumber = 0; triviaLineNumber < triviaLines.Length; triviaLineNumber++)
            {
                if (!IsCode(triviaLines[triviaLineNumber]))
                {
                    continue;
                }

                var triviaStartingLineNumber = comment.GetLocation().GetLineSpan().StartLinePosition.Line;
                var lineNumber      = triviaStartingLineNumber + triviaLineNumber;
                var lineSpan        = c.Tree.GetText().Lines[lineNumber].Span;
                var commentLineSpan = lineSpan.Intersection(comment.GetLocation().SourceSpan);

                var location = Location.Create(c.Tree, commentLineSpan ?? lineSpan);
                c.ReportDiagnostic(Diagnostic.Create(Rule, location));
                return;
            }
        }
        private static void HandleMultiLineComment(SyntaxTreeAnalysisContext context, SyntaxTrivia multiLineComment)
        {
            var nodeText = multiLineComment.ToString();

            // We remove the /* and the */ and determine if the comment has any content.
            var commentText = nodeText.Substring(2, nodeText.Length - 4);

            if (string.IsNullOrWhiteSpace(commentText))
            {
                var diagnostic = Diagnostic.Create(Descriptor, multiLineComment.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
Пример #24
0
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.Span.Length <= 1)
            {
                return;
            }

            if (trivia.SyntaxTree.GetMappedLineSpan(trivia.Span).StartLinePosition.Character == 0)
            {
                return;
            }

            SyntaxToken token = trivia.Token;
            SyntaxToken precedingToken;
            SyntaxToken followingToken;

            int index;
            SyntaxTriviaList list;

            if ((index = token.LeadingTrivia.IndexOf(trivia)) >= 0)
            {
                precedingToken = token.GetPreviousToken();
                followingToken = token;
                list           = token.LeadingTrivia;
            }
            else if ((index = token.TrailingTrivia.IndexOf(trivia)) >= 0)
            {
                precedingToken = token;
                followingToken = precedingToken.GetNextToken();
                list           = token.TrailingTrivia;
            }
            else
            {
                // shouldn't be reachable, but either way can't proceed
                return;
            }

            var followingTrivia = index + 1 < list.Count ? list[index + 1] : default(SyntaxTrivia);

            if (precedingToken.IsKind(SyntaxKind.CommaToken) ||
                precedingToken.IsKind(SyntaxKind.SemicolonToken) ||
                followingTrivia.IsKind(SyntaxKind.EndOfLineTrivia) ||
                followingToken.IsKind(SyntaxKind.EndOfFileToken))
            {
                return;
            }

            // Code must not contain multiple whitespace characters in a row.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #25
0
        private void AnalyzeSyntaxNode(SyntaxNodeAnalysisContext context)
        {
            if (GeneratedCodeAnalyzer?.IsGeneratedCode(context) == true)
            {
                return;
            }

            var declaration = (MemberDeclarationSyntax)context.Node;

            if (declaration.Parent?.IsKind(SyntaxKind.CompilationUnit) == false)
            {
                TokenPair tokenPair = GetTokenPair(declaration);

                if (!tokenPair.OpenToken.IsKind(SyntaxKind.None) &&
                    !tokenPair.OpenToken.IsMissing &&
                    !tokenPair.CloseToken.IsKind(SyntaxKind.None) &&
                    !tokenPair.CloseToken.IsMissing)
                {
                    int closeTokenLine = tokenPair.CloseToken.GetSpanEndLine();

                    if (tokenPair.OpenToken.GetSpanEndLine() != closeTokenLine)
                    {
                        MemberDeclarationSyntax nextDeclaration = GetNextDeclaration(declaration);

                        if (nextDeclaration != null)
                        {
                            int diff = nextDeclaration.GetSpanStartLine() - closeTokenLine;

                            if (diff < 2)
                            {
                                SyntaxTrivia trivia = declaration.GetTrailingTrivia().LastOrDefault();

                                if (trivia.IsKind(SyntaxKind.EndOfLineTrivia))
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.AddEmptyLineBetweenDeclarations,
                                        trivia.GetLocation());
                                }
                                else
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.AddEmptyLineBetweenDeclarations,
                                        tokenPair.CloseToken.GetLocation());
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #26
0
 private static void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
 {
     // We can ignore structured trivia like directives (e.g., #region, #pragma) and XML comments.
     if (!trivia.HasStructure)
     {
         // We only need to look at leading trivia.  It's ok to use spaces between keywords (e.g., private void Method()),
         // and those usually show up as trailing trivia.  However, sometimes spaces between identifiers show up as leading
         // trivia (e.g., in <param name="X">).  So we have to make sure the leading trivia is really at the beginning of a line.
         SyntaxToken token = trivia.Token;
         if (token.LeadingTrivia.IndexOf(trivia) >= 0 &&
             trivia.ToFullString().IndexOf(' ') >= 0 &&
             trivia.GetLineSpan().StartLinePosition.Character == 0)
         {
             context.ReportDiagnostic(Diagnostic.Create(Rule, trivia.GetLocation()));
         }
     }
 }
        public static void Analyze(SyntaxNodeAnalysisContext context, MemberDeclarationSyntax declaration)
        {
            if (!declaration.IsParentKind(SyntaxKind.CompilationUnit))
            {
                TokenPair   tokenPair  = GetTokenPair(declaration);
                SyntaxToken openToken  = tokenPair.OpenToken;
                SyntaxToken closeToken = tokenPair.CloseToken;

                if (!openToken.IsKind(SyntaxKind.None) &&
                    !openToken.IsMissing &&
                    !closeToken.IsKind(SyntaxKind.None) &&
                    !closeToken.IsMissing)
                {
                    int closeTokenLine = closeToken.GetSpanEndLine();

                    if (openToken.GetSpanEndLine() != closeTokenLine)
                    {
                        MemberDeclarationSyntax nextDeclaration = GetNextDeclaration(declaration);

                        if (nextDeclaration != null)
                        {
                            int diff = nextDeclaration.GetSpanStartLine() - closeTokenLine;

                            if (diff < 2)
                            {
                                SyntaxTrivia trivia = declaration.GetTrailingTrivia().LastOrDefault();

                                if (trivia.IsKind(SyntaxKind.EndOfLineTrivia))
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.AddEmptyLineBetweenDeclarations,
                                        trivia.GetLocation());
                                }
                                else
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.AddEmptyLineBetweenDeclarations,
                                        closeToken.GetLocation());
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #28
0
        private void HandleSingleLineCommentTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            string text = trivia.ToFullString();

            if (text.Equals("//") || text.StartsWith("// "))
            {
                return;
            }

            // special case: commented code
            if (text.StartsWith("////"))
            {
                return;
            }

            // Single line comment must begin with a space.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #29
0
        internal static MyToken Create(int index, SyntaxTrivia trivia)
        {
            var loc              = trivia.GetLocation();
            var lineInfo         = loc.GetLineSpan();
            var genericTokenType = GetGenericType(trivia.Kind(), false);
            var t = new MyToken
            {
                Index       = index,
                LineNumber  = lineInfo.StartLinePosition.Line,
                RawType     = trivia.Kind().ToString(),
                GenericType = genericTokenType,
                Text        = trivia.ToString(),
                StartPos    = loc.SourceSpan.Start,
                EndPos      = loc.SourceSpan.End,
                IsTrivia    = true
            };

            return(t);
        }
        private static void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            string fullString = trivia.ToFullString();

            if (fullString.StartsWith("////"))
            {
                // This is a line of commented code.
                return;
            }

            if (fullString.IndexOf('\t') < 0)
            {
                // No hard tabs were found.
                return;
            }

            // Tabs must not be used.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #31
0
        private static void Analyze(SyntaxNodeAnalysisContext context)
        {
            CompilationUnitSyntax node = (CompilationUnitSyntax)context.Node;

            if (Helper.IsGeneratedCode(context) || Helper.IsAssemblyInfo(context) || Helper.HasAutoGeneratedComment(node))
            {
                return;
            }

            if (node.FindToken(0).IsKind(SyntaxKind.EndOfFileToken))
            {
                return;
            }

            var first = node.GetLeadingTrivia();

            if (!first.Any())
            {
                CreateDiagnostic(context, node.GetLocation());
                return;
            }

            SyntaxTrivia copyrightSyntax = first[0];

            if (first[0].IsKind(SyntaxKind.RegionDirectiveTrivia))
            {
                if (first.Count < 2 || !first[1].IsKind(SyntaxKind.SingleLineCommentTrivia))
                {
                    CreateDiagnostic(context, context.Node.GetLocation());
                    return;
                }
                copyrightSyntax = first[1];
            }

            bool isCorrectStatement = CheckCopyrightStatement(context, copyrightSyntax);

            if (!isCorrectStatement)
            {
                CreateDiagnostic(context, copyrightSyntax.GetLocation());
                return;
            }
        }
Пример #32
0
 public override void VisitTrivia(SyntaxTrivia trivia)
 {
     cancellationToken.ThrowIfCancellationRequested();
     if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia) ||
         trivia.IsKind(SyntaxKind.MultiLineCommentTrivia) ||
         trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia))
     {
         var trimmedContent = trivia.ToString().TrimStart('/', ' ', '*');
         foreach (string tag in tagComments)
         {
             if (!trimmedContent.StartsWith(tag, StringComparison.Ordinal))
             {
                 continue;
             }
             var loc = trivia.GetLocation().GetLineSpan();
             Tags.Add(new Tag(tag, trimmedContent, new DocumentRegion(loc.StartLinePosition, loc.EndLinePosition)));
             break;
         }
     }
 }
Пример #33
0
            void Mark(SyntaxTrivia trivia, string type, JObject props = null)
            {
                var location  = trivia.GetLocation().GetLineSpan();
                var startLine = location.StartLinePosition.Line;
                var endLine   = location.EndLinePosition.Line;

                for (var i = startLine; i <= endLine; i++)
                {
                    var start = i == startLine ? location.StartLinePosition.Character : 0;
                    var end   = i == endLine ? location.EndLinePosition.Character : int.MaxValue;

                    _regions.Add(new Region
                    {
                        Line  = i,
                        Start = start,
                        End   = end,
                        Style = type,
                        Props = props
                    });
                }
            }
			public override void VisitTrivia (SyntaxTrivia trivia)
			{
				base.VisitTrivia (trivia);
				if (trivia.IsKind (SyntaxKind.RegionDirectiveTrivia)) {
					regionStack.Push (trivia);
				} else if (trivia.IsKind (SyntaxKind.EndRegionDirectiveTrivia)) {
					if (regionStack.Count == 0)
						return;
					var regionStart = regionStack.Pop ();
					try {
						var first = regionStart.GetLocation ().GetLineSpan ();
						var last = trivia.GetLocation ().GetLineSpan ();
						var v = regionStart.ToString ();
						v = v.Substring ("#region".Length).Trim ();
						if (v.Length == 0)
							v = "...";
						Foldings.Add (new FoldingRegion(v, new DocumentRegion(first.StartLinePosition, last.EndLinePosition), FoldType.UserRegion, true));
					} catch (ArgumentOutOfRangeException) { }
				}
			}
			public override void VisitTrivia (SyntaxTrivia trivia)
			{
				cancellationToken.ThrowIfCancellationRequested ();
				if (trivia.IsKind (SyntaxKind.SingleLineCommentTrivia) || 
					trivia.IsKind (SyntaxKind.MultiLineCommentTrivia) || 
					trivia.IsKind (SyntaxKind.SingleLineDocumentationCommentTrivia)) {
					var trimmedContent = trivia.ToString ().TrimStart ('/', ' ', '*');
					foreach (string tag in tagComments) {
						if (!trimmedContent.StartsWith (tag, StringComparison.Ordinal))
							continue;
						var loc = trivia.GetLocation ().GetLineSpan ();
						Tags.Add (new Tag (tag, trimmedContent, new DocumentRegion (loc.StartLinePosition, loc.EndLinePosition)));
						break;
					}
				}
			}
        private static void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            string fullString = trivia.ToFullString();
            if (fullString.StartsWith("////"))
            {
                // This is a line of commented code.
                return;
            }

            if (fullString.IndexOf('\t') < 0)
            {
                // No hard tabs were found.
                return;
            }

            // Tabs must not be used.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
Пример #37
0
        private static void CheckMultilineComment(SyntaxTreeAnalysisContext c, SyntaxTrivia comment)
        {
            var triviaContent = GetTriviaContent(comment);
            var triviaLines = triviaContent.Split(MetricsBase.LineTerminators, StringSplitOptions.None);

            for (var triviaLineNumber = 0; triviaLineNumber < triviaLines.Length; triviaLineNumber++)
            {
                if (!IsCode(triviaLines[triviaLineNumber]))
                {
                    continue;
                }

                var triviaStartingLineNumber = comment.GetLocation().GetLineSpan().StartLinePosition.Line;
                var lineNumber = triviaStartingLineNumber + triviaLineNumber;
                var lineSpan = c.Tree.GetText().Lines[lineNumber].Span;
                var commentLineSpan = lineSpan.Intersection(comment.GetLocation().SourceSpan);

                var location = Location.Create(c.Tree, commentLineSpan ?? lineSpan);
                c.ReportDiagnostic(Diagnostic.Create(Rule, location));
                return;
            }
        }
        private void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.Span.Length <= 1)
            {
                return;
            }

            if (trivia.SyntaxTree.GetMappedLineSpan(trivia.Span).StartLinePosition.Character == 0)
            {
                return;
            }

            SyntaxToken token = trivia.Token;
            SyntaxToken precedingToken;
            SyntaxToken followingToken;
            if (token.LeadingTrivia.Contains(trivia))
            {
                precedingToken = token.GetPreviousToken();
                followingToken = token;
            }
            else if (token.TrailingTrivia.Contains(trivia))
            {
                precedingToken = token;
                followingToken = precedingToken.GetNextToken();
            }
            else
            {
                // shouldn't be reachable, but either way can't proceed
                return;
            }

            if (precedingToken.IsKind(SyntaxKind.CommaToken) || precedingToken.IsKind(SyntaxKind.SemicolonToken))
            {
                return;
            }

            // Code must not contain multiple whitespace characters in a row.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
        private static void HandleWhitespaceTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia)
        {
            if (trivia.Span.Length <= 1)
            {
                return;
            }

            if (trivia.SyntaxTree.GetMappedLineSpan(trivia.Span).StartLinePosition.Character == 0)
            {
                return;
            }

            SyntaxToken token = trivia.Token;
            SyntaxToken precedingToken;
            SyntaxToken followingToken;

            int index;
            SyntaxTriviaList list;

            if ((index = token.LeadingTrivia.IndexOf(trivia)) >= 0)
            {
                precedingToken = token.GetPreviousToken();
                followingToken = token;
                list = token.LeadingTrivia;
            }
            else if ((index = token.TrailingTrivia.IndexOf(trivia)) >= 0)
            {
                precedingToken = token;
                followingToken = precedingToken.GetNextToken();
                list = token.TrailingTrivia;
            }
            else
            {
                // shouldn't be reachable, but either way can't proceed
                return;
            }

            var followingTrivia = index + 1 < list.Count ? list[index + 1] : default(SyntaxTrivia);

            if (precedingToken.IsKind(SyntaxKind.CommaToken)
                || precedingToken.IsKind(SyntaxKind.SemicolonToken)
                || followingTrivia.IsKind(SyntaxKind.EndOfLineTrivia)
                || followingToken.IsKind(SyntaxKind.EndOfFileToken))
            {
                return;
            }

            // Code must not contain multiple whitespace characters in a row.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }
        internal static GetFullCommentedCodeResult GetFullCommentedCode(SyntaxNode root, SyntaxTrivia firstComment)
        {
            var result = new StringBuilder();
            var current = firstComment;
            var numberOfComments = 1;
            var start = firstComment.GetLocation().SourceSpan.Start;
            int end;
            do
            {
                end = current.GetLocation().SourceSpan.End;
                result.Append(current.ToString().Substring(2));

                var eol = root.FindTrivia(current.GetLocation().SourceSpan.End + 1);
                if (!eol.IsKind(SyntaxKind.EndOfLineTrivia)) break;

                var whitespace = root.FindTrivia(eol.GetLocation().SourceSpan.End + 1);
                if (!whitespace.IsKind(SyntaxKind.WhitespaceTrivia)) break;

                current = root.FindTrivia(whitespace.GetLocation().SourceSpan.End + 1);
                if (!current.IsKind(SyntaxKind.SingleLineCommentTrivia)) break;

                numberOfComments ++;

            } while (true);
            return new GetFullCommentedCodeResult(result.ToString(), numberOfComments, start, end);
        }
Пример #41
0
            void Mark(SyntaxTrivia trivia, string type, JObject props = null)
            {
                var location = trivia.GetLocation().GetLineSpan();
                var startLine = location.StartLinePosition.Line;
                var endLine = location.EndLinePosition.Line;

                for (var i = startLine; i <= endLine; i++)
                {
                    var start = i == startLine ? location.StartLinePosition.Character : 0;
                    var end = i == endLine ? location.EndLinePosition.Character : int.MaxValue;

                    _regions.Add(new Region
                    {
                        Line = i,
                        Start = start,
                        End = end,
                        Style = type,
                        Props = props
                    });
                }
            }
        private static void HandleSingleLineComment(SyntaxTreeAnalysisContext context, SyntaxTrivia singleLineComment)
        {
            int index = 0;

            // PERF: Explicitly cast to IReadOnlyList so we only box once.
            IReadOnlyList<SyntaxTrivia> list = TriviaHelper.GetContainingTriviaList(singleLineComment, out index);
            var firstNonWhiteSpace = TriviaHelper.IndexOfFirstNonWhitespaceTrivia(list);

            // When we encounter a block of single line comments, we only want to raise this diagnostic
            // on the first or last line.  This ensures that whitespace in code commented out using
            // the Comment Selection option in Visual Studio will not raise the diagnostic for every
            // blank line in the code which is commented out.
            bool isFirst = index == firstNonWhiteSpace;
            if (!isFirst)
            {
                // This is -2 because we need to go back past the end of line trivia as well.
                var lastNonWhiteSpace = TriviaHelper.IndexOfTrailingWhitespace(list) - 2;
                if (index != lastNonWhiteSpace)
                {
                    return;
                }
            }

            if (IsNullOrWhiteSpace(singleLineComment.ToString(), 2))
            {
                var diagnostic = Diagnostic.Create(Descriptor, singleLineComment.GetLocation());
                context.ReportDiagnostic(diagnostic);
            }
        }
        private static void HandleSingleLineCommentTrivia(SyntaxTreeAnalysisContext context, SyntaxTrivia trivia, bool isFirstSingleLineTrivia)
        {
            string text = trivia.ToFullString();
            if (text.Equals(@"//"))
            {
                return;
            }

            // special case: commented code or documentation if the parsers documentation mode is DocumentationMode.None
            if (text.StartsWith(@"///", StringComparison.Ordinal))
            {
                return;
            }

            // Special case: multiple dashes at start of comment
            if (text.StartsWith(@"//--", StringComparison.Ordinal))
            {
                return;
            }

            // Special case: //\ negates spacing requirements
            if (text.StartsWith(@"//\", StringComparison.Ordinal))
            {
                return;
            }

            // No need to handle documentation comments ("///") because they're not
            // reported as SingleLineCommentTrivia.
            int spaceCount = 0;
            for (int i = 2; (i < text.Length) && (text[i] == ' '); i++)
            {
                spaceCount++;
            }

            if (spaceCount == 1)
            {
                return;
            }

            // Special case: follow-on comment lines may be indented with more than
            // one space.
            if (spaceCount > 1 && !isFirstSingleLineTrivia)
            {
                return;
            }

            // Single line comment must begin with a space.
            context.ReportDiagnostic(Diagnostic.Create(Descriptor, trivia.GetLocation()));
        }