Esempio n. 1
0
        private static void OnBuildConfigFinished(vsBuildScope Scope, vsBuildAction Action)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            // Sometimes we get this message several times.
            if (!CompilationOngoing)
            {
                return;
            }

            // Parsing maybe successful for an unsuccessful build!
            bool successfulParsing = true;

            try
            {
                string outputText = VSUtils.GetOutputText();
                if (string.IsNullOrEmpty(outputText))
                {
                    successfulParsing = false;
                    return;
                }

                // What we're building right now is a tree.
                // However, combined with the existing data it might be a wide graph.
                var includeTreeItemStack = new Stack <IncludeGraph.GraphItem>();
                includeTreeItemStack.Push(graphBeingExtended.CreateOrGetItem(documentBeingCompiled.FullName, out _));

                var includeDirectories = VSUtils.GetProjectIncludeDirectories(documentBeingCompiled.ProjectItem.ContainingProject);
                includeDirectories.Insert(0, PathUtil.Normalize(documentBeingCompiled.Path) + Path.DirectorySeparatorChar);

                const string includeNoteString = "Note: including file: ";
                string[]     outputLines       = System.Text.RegularExpressions.Regex.Split(outputText, "\r\n|\r|\n"); // yes there are actually \r\n in there in some VS versions.
                foreach (string line in outputLines)
                {
                    int startIndex = line.IndexOf(includeNoteString);
                    if (startIndex < 0)
                    {
                        continue;
                    }
                    startIndex += includeNoteString.Length;

                    int includeStartIndex = startIndex;
                    while (includeStartIndex < line.Length && line[includeStartIndex] == ' ')
                    {
                        ++includeStartIndex;
                    }
                    int depth = includeStartIndex - startIndex;

                    if (depth >= includeTreeItemStack.Count)
                    {
                        includeTreeItemStack.Push(includeTreeItemStack.Peek().Includes.Last().IncludedFile);
                    }
                    while (depth < includeTreeItemStack.Count - 1)
                    {
                        includeTreeItemStack.Pop();
                    }

                    string fullIncludePath = line.Substring(includeStartIndex);
                    IncludeGraph.GraphItem includedItem = graphBeingExtended.CreateOrGetItem(fullIncludePath, out _);
                    includeTreeItemStack.Peek().Includes.Add(new IncludeGraph.Include()
                    {
                        IncludedFile = includedItem
                    });
                }
            }

            catch (Exception e)
            {
                _ = Output.Instance.ErrorMsg("Failed to parse output from /showInclude compilation of file '{0}': {1}", documentBeingCompiled.FullName, e);
                successfulParsing = false;
                return;
            }
            finally
            {
                _ = onCompleted(graphBeingExtended, documentBeingCompiled, successfulParsing);
                _ = ResetPendingCompilationInfo();
            }
        }
        private static void OnBuildConfigFinished(vsBuildScope Scope, vsBuildAction Action)
        {
            // Sometimes we get this message several times.
            if (!CompilationOngoing)
            {
                return;
            }

            // Parsing maybe successful for an unsuccessful build!
            bool successfulParsing = true;

            try
            {
                string outputText = VSUtils.GetOutputText();
                if (string.IsNullOrEmpty(outputText))
                {
                    successfulParsing = false;
                    return;
                }

                // What we're building right now is a tree.
                // However, combined with the existing data it might be a wide graph.
                var includeTreeItemStack = new Stack <IncludeGraph.GraphItem>();
                includeTreeItemStack.Push(graphBeingExtended.CreateOrGetItem(documentBeingCompiled.FullName, 0.0, out _));

                var includeDirectories = VSUtils.GetProjectIncludeDirectories(documentBeingCompiled.ProjectItem.ContainingProject);
                includeDirectories.Insert(0, PathUtil.Normalize(documentBeingCompiled.Path) + Path.DirectorySeparatorChar);

                const string includeHeadersString = "Include Headers:";
                string[]     outputLines          = System.Text.RegularExpressions.Regex.Split(outputText, "\r\n|\r|\n"); // yes there are actually \r\n in there in some VS versions.

                /*
                 * mode:
                 * - 0 means not in a parsing mode
                 * - 1 means parsing 'Include Headers:' section
                 */
                int mode = 0;
                for (int line_index = 0; line_index < outputLines.Count(); line_index++)
                {
                    string line = outputLines[line_index];
                    // keeping track parsing state
                    if (mode == 0)
                    {
                        if (line.IndexOf(includeHeadersString) >= 0)
                        {
                            mode = 1;
                            continue;
                        }
                        // hack we do not support other states yet
                        continue;
                    }

                    line = CleanString(line);
                    int count = ParseInt(line, "Count:");
                    for (int include_line_index = 0; include_line_index < count; include_line_index++)
                    {
                        line_index++;
                        string include_line = outputLines[line_index];
                        include_line = CleanString(include_line);
                        int depth = include_line.Count(f => f == '\t') - 1;

                        if (depth >= includeTreeItemStack.Count)
                        {
                            includeTreeItemStack.Push(includeTreeItemStack.Peek().Includes.Last().IncludedFile);
                        }
                        while (depth < includeTreeItemStack.Count - 1)
                        {
                            includeTreeItemStack.Pop();
                        }

                        var filename_and_time = GetFilenameAndTime(include_line);
                        IncludeGraph.GraphItem includedItem = graphBeingExtended.CreateOrGetItem(filename_and_time.filename, filename_and_time.time, out _);
                        includeTreeItemStack.Peek().Includes.Add(new IncludeGraph.Include()
                        {
                            IncludedFile = includedItem
                        });
                    }

                    mode = 0;
                }
            }

            catch (Exception e)
            {
                Output.Instance.ErrorMsg("Failed to parse output from -d1reportTime compilation of file '{0}': {1}", documentBeingCompiled.FullName, e);
                successfulParsing = false;
                return;
            }
            finally
            {
                try
                {
                    onCompleted(graphBeingExtended, successfulParsing);
                }
                finally
                {
                    ResetPendingCompilationInfo();
                }
            }
        }