/// <summary>
        /// Inspects the syntax tree and reports the comments starting with the expected prefixes.
        /// </summary>
        /// <param name="tree">Parsed syntax tree</param>
        /// <param name="rules">Rules of the inspection</param>
        /// <returns>List of comments starting with the given prefixes</returns>
        public static IEnumerable <Record> Inspect(SyntaxTree tree, Rules rules)
        {
            var root = (CompilationUnitSyntax)tree.GetRoot();

            var irrelevantRecord = new Record("", "", 0, 0, Status.Ok);

            IEnumerable <Record> records =
                root.DescendantTrivia()
                // Beware: ToString() is an expensive operation on Syntax Nodes and
                // involves some complex logic and a string builder!
                // Hence we convert the trivia to string only at this single place.
                .Select((trivia) => (trivia, trivia.ToString()))
                .Select(
                    ((SyntaxTrivia, string)t) =>
            {
                var(trivia, triviaAsString) = t;

                var result = Text.Inspect(triviaAsString, rules);
                if (result == null)
                {
                    return(irrelevantRecord);
                }

                var span     = tree.GetLineSpan(trivia.Span);
                var position = span.StartLinePosition;
                var line     = position.Line;
                var column   = position.Character;

                return(new Record(result.Prefix, result.Suffix, line, column, result.Status));
            })
        public static string CreateUniqueVariableName(Microsoft.CodeAnalysis.SyntaxTree syntaxTree, string baseName)
        {
            var contextNode = syntaxTree.GetRoot();

            var symbols = contextNode.DescendantNodes().OfType <MethodDeclarationSyntax>().Select(n => n.Identifier.ValueText).ToList();

            symbols.AddRange(contextNode.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().Select(n => n.Declaration.Variables.FirstOrDefault().Identifier.ValueText).ToList());
            symbols.AddRange(contextNode.DescendantNodes().OfType <FieldDeclarationSyntax>().Select(n => n.Declaration.Variables.FirstOrDefault().Identifier.ValueText).ToList());
            symbols.AddRange(contextNode.DescendantNodes().OfType <ParameterSyntax>().Select(n => n.Identifier.ValueText).ToList());

            return(GenerateUniqueName(baseName, string.Empty,
                                      n => symbols.Where(x => x.Equals(n)).ToArray().Length == 0));
        }
Exemple #3
0
        public static string CreateUniqueVariableName(Microsoft.CodeAnalysis.SyntaxTree syntaxTree, string baseName)
        {
            var contextNode = syntaxTree.GetRoot();

            var symbols = contextNode.DescendantNodes().OfType <MethodDeclarationSyntax>().Select(n => n.Identifier.ValueText).ToList();

            symbols.AddRange(contextNode.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().Select(n => n.Declaration.Variables.FirstOrDefault().Identifier.ValueText).ToList());
            symbols.AddRange(contextNode.DescendantNodes().OfType <FieldDeclarationSyntax>().Select(n => n.Declaration.Variables.FirstOrDefault().Identifier.ValueText).ToList());
            symbols.AddRange(contextNode.DescendantNodes().OfType <ParameterSyntax>().Select(n => n.Identifier.ValueText).ToList());

            var existingNames = new HashSet <string>(symbols);

            return(baseName.GetUniqueName(existingNames));
        }
        private static void UpdateCSFileCodes(Client client, SoftwareFile softwareFile, ref AppsClient.AppsResult result)
        {
            var softwareFileCodeDB = client.DB.GetCollection <SoftwareFileCode>("SoftwareFileCodes");

            Microsoft.CodeAnalysis.SyntaxTree tree = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(softwareFile.Contents);
            var descendents = tree.GetRoot().DescendantNodes(); //.OfType<LiteralExpressionSyntax>();

            foreach (var desc in descendents)
            {
                if (desc.GetType().Name == "MethodDeclarationSyntax")
                {
                    var method = (MethodDeclarationSyntax)desc;

                    var existingCodeList = softwareFile.SoftwareFileCodes.Where(sc => sc.Name == method.Identifier.Text);
                    if (existingCodeList.Count() == 1)
                    {
                        var existingCode = existingCodeList.Single();
                        existingCode.CodeType       = SoftwareFileCodeTypes.Method;
                        existingCode.Contents       = method.Body.ToFullString();
                        existingCode.Name           = method.Identifier.Text;
                        existingCode.SoftwareFileID = softwareFile.SoftwareFileID;

                        softwareFileCodeDB.Upsert(existingCode);
                    }
                    else if (existingCodeList.Count() == 0)
                    {
                        var newCode = new SoftwareFileCode
                        {
                            CodeType                                           = SoftwareFileCodeTypes.Method,
                            Contents                                           = method.Body != null?method.Body.ToFullString() : "",
                                                                Name           = method.Identifier.Text,
                                                                SoftwareFileID = softwareFile.SoftwareFileID
                        };

                        softwareFileCodeDB.Insert(newCode);

                        softwareFile.SoftwareFileCodes.Add(newCode);
                    }
                    else
                    {
                        result.FailMessages.Add("More than one code found for " + method.Identifier.Text + " in file " + softwareFile.FullName);
                    }
                }
            }
        }
Exemple #5
0
        private static IEnumerable <SuspectTrivia> InspectTrivias(SyntaxTree tree)
        {
            var root = (CompilationUnitSyntax)tree.GetRoot();

            var tracker = new OnOffTracker();

            var relevantTrivias =
                root.DescendantTrivia()
                // Beware: ToString() is an expensive operation on Syntax Nodes and
                // involves some complex logic and a string builder!
                // Hence we convert the trivia to string only at this single place.
                .Select((trivia) => (trivia, trivia.ToString()))
                .Where(
                    (t) =>
            {
                var(_, triviaAsString) = t;
                tracker.Feed(triviaAsString);

                return(tracker.IsOn &&
                       TriviaIsComment(triviaAsString) &&
                       !ShouldSkipTrivia(triviaAsString));
            });

            foreach (var(trivia, triviaAsString) in relevantTrivias)
            {
                var span     = tree.GetLineSpan(trivia.Span);
                var position = span.StartLinePosition;

                List <Cue>?cues = InspectComment(position.Line, position.Character, triviaAsString);

                if (cues != null)
                {
                    yield return(new SuspectTrivia(trivia, cues));
                }
            }
        }
Exemple #6
0
 public void Apply(ref Microsoft.CodeAnalysis.SyntaxTree syntaxTree, CompilationOptions options)
 {
     syntaxTree = new InstrumentForInEditorDebugging().Visit(syntaxTree.GetRoot()).SyntaxTree;
     // TODO handle exceptions again: syntaxTree = new ExceptionHandlingInjection().Visit(syntaxTree.GetRoot()).SyntaxTree;
 }
Exemple #7
0
        public static DoctestsAndErrors Extract(SyntaxTree tree)
        {
            var doctests = new List <Doctest>();
            var errors   = new List <Error>();

            // stack
            var stack = new Stack <NamespaceWip>();

            // Push the Work-in-progress for the global namespace
            stack.Push(new NamespaceWip {
                Namespace = "", SpanEnd = tree.Length
            });

            var root = (CompilationUnitSyntax)tree.GetRoot();

            foreach (var node in NamespaceDeclsAndDocumentations(root))
            {
                if (node.SpanStart >= stack.Peek().SpanEnd)
                {
                    var wip = stack.Pop();
                    if (wip.Doctests.Count > 0)
                    {
                        doctests.AddRange(wip.Doctests);
                    }
                }

                switch (node)
                {
                case Syntax.DocumentationCommentTriviaSyntax documentation:
                    List <Pipeline.Code> codes = Pipeline.CodesFromDocumentation(documentation);

                    List <Pipeline.DoctestWithoutNamespaceOrError> dtWoNsOrErrorList =
                        codes.Select(Pipeline.SplitHeaderBody).ToList();

                    stack.Peek().Doctests.AddRange(
                        dtWoNsOrErrorList
                        .Where((dtOrErr) => dtOrErr.DoctestWithoutNamespace != null)
                        .Select((dtOrErr) => new Doctest(
                                    stack.Peek().Namespace,
                                    dtOrErr.DoctestWithoutNamespace !.Usings,
                                    dtOrErr.DoctestWithoutNamespace !.Body,
                                    dtOrErr.DoctestWithoutNamespace !.Line,
                                    dtOrErr.DoctestWithoutNamespace !.Column)));

                    errors.AddRange(
                        dtWoNsOrErrorList
                        .Where((dtOrErr) => dtOrErr.Error != null)
                        .Select((dtOrErr) => dtOrErr.Error !));

                    break;

                case Syntax.NamespaceDeclarationSyntax namespaceDecl:
                    string ns = (stack.Peek().Namespace == "")
                            ? namespaceDecl.Name.ToString()
                            : $"{stack.Peek().Namespace}.{namespaceDecl.Name.ToString()}";

                    stack.Push(new NamespaceWip
                    {
                        Namespace = ns,
                        SpanEnd   = namespaceDecl.Span.End
                    });

                    break;

                default:
                    continue;
                }
            }

            while (stack.Count != 0)
            {
                var wip = stack.Pop();
                if (wip.Doctests.Count > 0)
                {
                    doctests.AddRange(wip.Doctests);
                }
            }

            // Sort doctests by line and column
            doctests.Sort((doctest, otherDoctest) =>
            {
                int ret = doctest.Line.CompareTo(otherDoctest.Line);
                if (ret == 0)
                {
                    ret = doctest.Column.CompareTo(otherDoctest.Column);
                }

                return(ret);
            });

            return(new DoctestsAndErrors(doctests, errors));
        }
        static List <CGFDocument> ProcessDocuments(CGFParserReporter reporter, List <Microsoft.CodeAnalysis.Document> documents, Microsoft.CodeAnalysis.Project project)
        {
            using (reporter.CreateContextScope(CGFParserReporterContext.Type.Project, project.FilePath))
            {
                List <CGFDocument> documentsToProcess = new List <CGFDocument>();
                foreach (Microsoft.CodeAnalysis.Document document in documents)
                {
                    using (reporter.CreateContextScope(CGFParserReporterContext.Type.File, document.FilePath))
                    {
                        List <CGFTypeSymbol> typesToProcess = new List <CGFTypeSymbol>();

                        Microsoft.CodeAnalysis.SemanticModel semanticModel = document.GetSemanticModelAsync().Result;

                        Microsoft.CodeAnalysis.SyntaxTree syntaxTree = document.GetSyntaxTreeAsync().Result;
                        IEnumerable <Microsoft.CodeAnalysis.SyntaxNode> syntaxNodes = syntaxTree.GetRoot().DescendantNodes().Where(n => (n as ClassDeclarationSyntax) != null || (n as EnumDeclarationSyntax) != null);
                        foreach (Microsoft.CodeAnalysis.SyntaxNode node in syntaxNodes)
                        {
                            ClassDeclarationSyntax classSyntax = node as ClassDeclarationSyntax;
                            if (classSyntax != null)
                            {
                                Microsoft.CodeAnalysis.INamedTypeSymbol typeSymbol = semanticModel.GetDeclaredSymbol(classSyntax);
                                using (reporter.CreateContextScope(CGFParserReporterContext.Type.Type, typeSymbol.Name))
                                {
                                    CGFTypeSymbol cgfTypeSymbol = CGFTypeSymbol.Parse(reporter, typeSymbol);
                                    typesToProcess.Add(cgfTypeSymbol);
                                }
                            }
                            else
                            {
                                EnumDeclarationSyntax enumSyntax = node as EnumDeclarationSyntax;
                                Microsoft.CodeAnalysis.INamedTypeSymbol typeSymbol = semanticModel.GetDeclaredSymbol(enumSyntax);

                                using (reporter.CreateContextScope(CGFParserReporterContext.Type.Type, typeSymbol.Name))
                                {
                                    CGFTypeSymbol cgfTypeSymbol = CGFTypeSymbol.Parse(reporter, typeSymbol);
                                    typesToProcess.Add(cgfTypeSymbol);
                                }
                            }
                        }

                        if (typesToProcess.Count > 0)
                        {
                            CGFDocument cgfDocument = CGFDocument.Parse(reporter, document, typesToProcess);
                            documentsToProcess.Add(cgfDocument);
                        }
                    }
                }

                return(documentsToProcess);
            }
        }