private static void AddNode(ItemCollection items, SyntaxNode node, string prefix)
        {
            var tooltip      = string.Join(Environment.NewLine, node.GetDiagnostics().Select(x => x.ToString()));
            var treeViewItem = new TreeViewItem
            {
                Background = (node.ContainsDiagnostics) ? Brushes.Pink : Brushes.Transparent,
                Foreground = (node.IsToken) ? Brushes.DarkGreen : (node.Ancestors().Any(a => a.IsToken) ? Brushes.DarkRed : Brushes.Blue),
                Header     = $"{prefix}{node.Kind} [{node.SourceRange.Start}..{node.SourceRange.End})",
                ToolTip    = string.IsNullOrEmpty(tooltip) ? null : tooltip,
                Tag        = node
            };

            foreach (var childNode in node.ChildNodes)
            {
                AddNode(treeViewItem.Items, childNode, string.Empty);
            }

            if (node.IsToken)
            {
                var token = (SyntaxToken)node;
                foreach (var childNode in token.LeadingTrivia)
                {
                    AddNode(treeViewItem.Items, childNode, "Lead: ");
                }
                foreach (var childNode in token.TrailingTrivia)
                {
                    AddNode(treeViewItem.Items, childNode, "Trail: ");
                }
            }

            items.Add(treeViewItem);
        }
Example #2
0
        private Result getResult(out IEnumerable <MemberDeclarationSyntax> members)
        {
            members = members_;

            if (all_ == 0)
            {
                bool codeFound = node_.GetDiagnostics().
                                 Where(error =>
                {
                    return(error.Id == "CS1022");
                }).Any();

                if (codeFound)
                {
                    return(Result.Code);
                }

                return(Result.Empty);
            }

            if (members_.Count == 0)
            {
                return(Result.Empty);
            }

            if (all_ == members_.Count)
            {
                return(Result.Class);
            }

            return(Result.Error);
        }
Example #3
0
        private void Recurse(
            SyntaxTreeAnalysisContext context,
            ReportDiagnostic severity,
            SyntaxNode node,
            CancellationToken cancellationToken
            )
        {
            if (
                node.ContainsDiagnostics &&
                node.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error)
                )
            {
                return;
            }

            if (IsBlockLikeStatement(node))
            {
                ProcessBlockLikeStatement(context, severity, node);
            }

            foreach (var child in node.ChildNodesAndTokens())
            {
                if (child.IsNode)
                {
                    Recurse(context, severity, child.AsNode() !, cancellationToken);
                }
            }
        }
        private void VerifyErrorCode(SyntaxNode node, params DiagnosticId[] expected)
        {
            var actual = node.GetDiagnostics().Select(e => e.DiagnosticId).ToList();

            // no error
            if ((expected.Length == 0) && (actual.Count == 0))
            {
                return;
            }

            // Parser might give more errors than expected & that's fine
            Assert.That(actual.Count, Is.GreaterThanOrEqualTo(expected.Length));
            Assert.That(actual.Count, Is.LessThanOrEqualTo(int.MaxValue));

            // necessary?
            if (actual.Count < expected.Length)
            {
                return;
            }

            foreach (var i in expected)
            {
                Assert.Contains(i, actual); // no order
            }
        }
Example #5
0
        public static bool HasErrors(this SyntaxNode node)
        {
            if (!node.ContainsDiagnostics) //fast path
            {
                return(false);
            }

            return(node.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error));
        }
Example #6
0
        /// <summary>
        /// check whether node contains error for itself but not from its child node
        /// </summary>
        public static bool HasDiagnostics(this SyntaxNode node)
        {
            var set = new HashSet <Diagnostic>(node.GetDiagnostics());

            foreach (var child in node.ChildNodes())
            {
                set.ExceptWith(child.GetDiagnostics());
            }

            return(set.Count > 0);
        }
Example #7
0
        public ParseTree Parse(SourceCodeFile sourceCodeFile)
        {
            CSharpRoslynParseTree result = null;

            var filePath = Path.Combine(sourceCodeFile.RelativePath, sourceCodeFile.Name);

            if (sourceCodeFile.Code != null)
            {
                SyntaxNode root = null;
                try
                {
                    SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCodeFile.Code, null, filePath);
                    result          = new CSharpRoslynParseTree(syntaxTree);
                    root            = syntaxTree.GetRoot();
                    result.Comments = root.DescendantTrivia().Where(node =>
                    {
                        SyntaxKind kind = node.Kind();
                        return(kind == SyntaxKind.SingleLineCommentTrivia ||
                               kind == SyntaxKind.MultiLineCommentTrivia ||
                               kind == SyntaxKind.SingleLineDocumentationCommentTrivia ||
                               kind == SyntaxKind.MultiLineDocumentationCommentTrivia ||
                               kind == SyntaxKind.DocumentationCommentExteriorTrivia ||
                               kind == SyntaxKind.XmlComment);
                    }).ToArray();

                    IEnumerable <Diagnostic> diagnostics = root.GetDiagnostics();
                    foreach (var diagnostic in diagnostics)
                    {
                        if (diagnostic.Severity == DiagnosticSeverity.Error &&
                            diagnostic.Id != "CS1029")
                        {
                            var textSpan = RoslynHelper.ConvertTextSpan(diagnostic.Location);
                            Logger.LogError(new ParsingException(filePath, message: diagnostic.ToString())
                            {
                                TextSpan = textSpan
                            });
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.LogError(new ParsingException(filePath, ex));
                    result = new CSharpRoslynParseTree();
                }
            }
            else
            {
                result = new CSharpRoslynParseTree();
            }
            result.FileName = filePath;
            result.FileData = sourceCodeFile.Code;

            return(result);
        }
Example #8
0
        public override void Visit(SyntaxNode node)
        {
            if (node?.ContainsDiagnostics == true)
            {
                var diagnostics = node.GetDiagnostics();

                _diagnostics.AddRange(diagnostics);

                base.Visit(node);
            }
        }
        public static void Deconstruct(
            this string text,
            out SyntaxTree tree,
            out string formatter,
            out IEnumerable <Diagnostic> errors)
        {
            tree = CSharpSyntaxTree.ParseText(text.Trim(), _options);
            SyntaxNode root = Formatter.Format(tree.GetCompilationUnitRoot(), _workSpace);

            tree      = root.SyntaxTree;
            formatter = root.ToString();
            errors    = root.GetDiagnostics();
        }
Example #10
0
        public ParseTree Parse(TextFile sourceFile, out TimeSpan parserTimeSpan)
        {
            if (sourceFile.Data == null)
            {
                return(null);
            }

            try
            {
                var        stopwatch  = Stopwatch.StartNew();
                var        filePath   = Path.Combine(sourceFile.RelativePath, sourceFile.Name);
                SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceFile.Data, null, filePath);
                var        result     = new CSharpRoslynParseTree(syntaxTree);
                SyntaxNode root       = syntaxTree.GetRoot();
                result.Comments = root.DescendantTrivia().Where(node =>
                {
                    SyntaxKind kind = node.Kind();
                    return(kind == SyntaxKind.SingleLineCommentTrivia ||
                           kind == SyntaxKind.MultiLineCommentTrivia ||
                           kind == SyntaxKind.SingleLineDocumentationCommentTrivia ||
                           kind == SyntaxKind.MultiLineDocumentationCommentTrivia ||
                           kind == SyntaxKind.DocumentationCommentExteriorTrivia ||
                           kind == SyntaxKind.XmlComment);
                }).ToArray();

                IEnumerable <Diagnostic> diagnostics = root.GetDiagnostics();
                foreach (Diagnostic diagnostic in diagnostics)
                {
                    if (diagnostic.Severity == DiagnosticSeverity.Error &&
                        diagnostic.Id != "CS1029")
                    {
                        var textSpan = diagnostic.Location.ToTextSpan();
                        Logger.LogError(new ParsingException(sourceFile, message: diagnostic.ToString())
                        {
                            TextSpan = textSpan
                        });
                    }
                }
                stopwatch.Stop();
                parserTimeSpan = stopwatch.Elapsed;

                result.SourceFile = sourceFile;
                return(result);
            }
            catch (Exception ex) when(!(ex is ThreadAbortException))
            {
                Logger.LogError(new ParsingException(sourceFile, ex));
                return(null);
            }
        }
        protected override EvaluationResult EvaluateImpl(SyntaxNode node)
        {
            // Roslyn does not handle async await keywords.
            var diagnostics = node.GetDiagnostics();

            if (diagnostics.Any(d => d.Severity != DiagnosticSeverity.Info))
            {
                return(new EvaluationResult
                {
                    Snippet = node.ToFullString()
                });
            }

            return(null);
        }
 /// <summary>
 /// Reads in a <see cref="SyntaxNode"/> and returns a <see cref="XmlSyntaxData"/>
 /// </summary>
 /// <param name="node">Parsed Xml Node</param>
 /// <param name="withChildren">Include children in this new node.</param>
 /// <returns>UI ready data.</returns>
 public static XmlSyntaxData FromNode(SyntaxNode node, bool withChildren = true)
 {
     return(new XmlSyntaxData()
     {
         HashId = node.GetHashCode(),
         Type = node.IsList ? "SyntaxList" : node.GetType().Name,
         TypeClass = node.IsList ? "list" : (node.IsToken ? "token" : "syntax"),
         Text = node.IsToken ? (node as SyntaxToken).Text : string.Empty,
         Errors = node.ContainsDiagnostics ?
                  node.GetDiagnostics().Select(d => new XmlSyntaxError()
         {
             Id = d.ErrorID,
             Description = d.GetDescription()
         }).ToList()
             : Array.Empty <XmlSyntaxError>().ToList(),
         SpanStart = node.FullSpan.Start,
         SpanEnd = node.FullSpan.End,
         Children = withChildren ? node.ChildNodes.Select(child => XmlSyntaxData.FromNode(child)).ToList() : Array.Empty <XmlSyntaxData>().ToList()
     });
 }
Example #13
0
        private void VerifyErrorCode(SyntaxNode node, params DiagnosticId[] expected)
        {
            var actual = node.GetDiagnostics().Select(e => e.DiagnosticId).ToList();

            // no error
            if ((expected.Length == 0) && (actual.Count == 0))
            {
                return;
            }

            // Parser might give more errors than expected & that's fine
            Assert.That(actual.Count, Is.GreaterThanOrEqualTo(expected.Length));
            Assert.That(actual.Count, Is.LessThanOrEqualTo(int.MaxValue));

            // necessary?
            if (actual.Count < expected.Length)
                return;

            foreach (var i in expected)
                Assert.Contains(i, actual); // no order
        }
        public static SyntaxNode GenerateViewModel(SyntaxNode node)
        {
            // Find the first class in the syntax node
            var classNode =
                node.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault();

            if (classNode != null)
            {
                var codeIssues = node.GetDiagnostics();
                if (!codeIssues.Any())
                {
                    // Get the name of the model class
                    var modelClassName = classNode.Identifier.Text;
                    // The name of the ViewModel class
                    var viewModelClassName = $"{modelClassName}ViewModel";
                    // Only for demo purposes, pluralizing an object is done by
                    // simply adding the "s" letter. Consider proper algorithms
                    string newImplementation =
                        $@"public class {viewModelClassName} : INotifyPropertyChanged
{{
public event PropertyChangedEventHandler PropertyChanged;
// Raise a property change notification
protected virtual void OnPropertyChanged(string propname)
{{
  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}}
private ObservableCollection<{modelClassName}> _{modelClassName}s;
public ObservableCollection<{modelClassName}> {modelClassName}s
{{
  get {{ return _{modelClassName}s; }}
  set
  {{
    _{modelClassName}s = value;
    OnPropertyChanged(nameof({modelClassName}s));
  }}
}}
public {viewModelClassName}() {{
// Implement your logic to load a collection of items
}}
}}
";
                    var newClassNode =
                        SyntaxFactory.ParseSyntaxTree(newImplementation).GetRoot()
                        .DescendantNodes().OfType <ClassDeclarationSyntax>()
                        .FirstOrDefault();
                    // Retrieve the parent namespace declaration
                    if (!(classNode.Parent is NamespaceDeclarationSyntax))
                    {
                        return(null);
                    }
                    var parentNamespace = (NamespaceDeclarationSyntax)classNode.Parent;
                    // Add the new class to the namespace
                    var newParentNamespace =
                        parentNamespace.AddMembers(newClassNode).NormalizeWhitespace();
                    return(newParentNamespace);
                }
                else
                {
                    foreach (Diagnostic codeIssue in codeIssues)
                    {
                        string issue = $"ID: {codeIssue.Id}, Message: {codeIssue.GetMessage()}, " +
                                       $"Location: {codeIssue.Location.GetLineSpan()}," +
                                       $"Severity: {codeIssue.Severity}";
                        Console.WriteLine(issue);
                    }
                    return(null);
                }
            }
            else
            {
                return(null);
            }
        }
        private static void AddNode(ItemCollection items, SyntaxNode node, string prefix)
        {
            var tooltip = string.Join(Environment.NewLine, node.GetDiagnostics().Select(x => x.ToString()));
            var treeViewItem = new TreeViewItem
            {
                Background = (node.ContainsDiagnostics) ? Brushes.Pink : Brushes.Transparent,
                Foreground = (node.IsToken) ? Brushes.DarkGreen : (node.Ancestors().Any(a => a.IsToken) ? Brushes.DarkRed : Brushes.Blue),
                Header = $"{prefix}{node.Kind} [{node.SourceRange.Start}..{node.SourceRange.End})",
                ToolTip = string.IsNullOrEmpty(tooltip) ? null : tooltip,
                Tag = node
            };

            foreach (var childNode in node.ChildNodes)
                AddNode(treeViewItem.Items, childNode, string.Empty);

            if (node.IsToken)
            {
                var token = (SyntaxToken) node;
                foreach (var childNode in token.LeadingTrivia)
                    AddNode(treeViewItem.Items, childNode, "Lead: ");
                foreach (var childNode in token.TrailingTrivia)
                    AddNode(treeViewItem.Items, childNode, "Trail: ");
            }

            items.Add(treeViewItem);
        }
Example #16
0
        private static async Task <(ImmutableArray <Diagnostic> reportedDiagnostics, ImmutableArray <string> unhandledIds)> GetReportedDiagnosticsForIdsAsync(
            ImmutableHashSet <string> idsToAnalyze,
            SyntaxNode root,
            SemanticModel semanticModel,
            CompilationWithAnalyzers compilationWithAnalyzers,
            Func <DiagnosticAnalyzer, ImmutableArray <DiagnosticDescriptor> > getSupportedDiagnostics,
            Func <DiagnosticAnalyzer, bool> getIsCompilationEndAnalyzer,
            PooledHashSet <string> compilerDiagnosticIds,
            CancellationToken cancellationToken)
        {
            using var _1 = ArrayBuilder <DiagnosticAnalyzer> .GetInstance(out var analyzersBuilder);

            using var _2 = ArrayBuilder <string> .GetInstance(out var unhandledIds);

            // First, we compute the relevant analyzers whose reported diagnostics need to be computed.
            var addedCompilerAnalyzer   = false;
            var hasNonCompilerAnalyzers = idsToAnalyze.Count > compilerDiagnosticIds.Count;

            foreach (var analyzer in compilationWithAnalyzers.Analyzers)
            {
                if (!addedCompilerAnalyzer &&
                    analyzer.IsCompilerAnalyzer())
                {
                    addedCompilerAnalyzer = true;
                    analyzersBuilder.Add(analyzer);

                    if (!hasNonCompilerAnalyzers)
                    {
                        break;
                    }

                    continue;
                }

                if (hasNonCompilerAnalyzers)
                {
                    Debug.Assert(!analyzer.IsCompilerAnalyzer());

                    bool?lazyIsUnhandledAnalyzer = null;
                    foreach (var descriptor in getSupportedDiagnostics(analyzer))
                    {
                        if (!idsToAnalyze.Contains(descriptor.Id))
                        {
                            continue;
                        }

                        lazyIsUnhandledAnalyzer ??= getIsCompilationEndAnalyzer(analyzer) || analyzer is IPragmaSuppressionsAnalyzer;
                        if (lazyIsUnhandledAnalyzer.Value)
                        {
                            unhandledIds.Add(descriptor.Id);
                        }
                    }

                    if (lazyIsUnhandledAnalyzer.HasValue && !lazyIsUnhandledAnalyzer.Value)
                    {
                        analyzersBuilder.Add(analyzer);
                    }
                }
            }

            // Then, we execute these analyzers on the current file to fetch these diagnostics.
            // Note that if an analyzer has already executed, then this will be just a cache access
            // as computed analyzer diagnostics are cached on CompilationWithAnalyzers instance.

            using var _3 = ArrayBuilder <Diagnostic> .GetInstance(out var reportedDiagnostics);

            if (!addedCompilerAnalyzer && compilerDiagnosticIds.Count > 0)
            {
                // Special case when compiler analyzer could not be found.
                Debug.Assert(semanticModel.Compilation.Options.ReportSuppressedDiagnostics);
                reportedDiagnostics.AddRange(root.GetDiagnostics());
                reportedDiagnostics.AddRange(semanticModel.GetDiagnostics(cancellationToken: cancellationToken));
                cancellationToken.ThrowIfCancellationRequested();
            }

            if (analyzersBuilder.Count > 0)
            {
                var analyzers = analyzersBuilder.ToImmutable();

                var syntaxDiagnostics = await compilationWithAnalyzers.GetAnalyzerSyntaxDiagnosticsAsync(semanticModel.SyntaxTree, analyzers, cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
                reportedDiagnostics.AddRange(syntaxDiagnostics);

                var semanticDiagnostics = await compilationWithAnalyzers.GetAnalyzerSemanticDiagnosticsAsync(semanticModel, filterSpan : null, analyzers, cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
                reportedDiagnostics.AddRange(semanticDiagnostics);
            }

            return(reportedDiagnostics.ToImmutable(), unhandledIds.ToImmutable());
        }