예제 #1
0
        public virtual void DoUpdateFileTags(MonoDevelop.Projects.Project project, string filename, IEnumerable <string> headers)
        {
            ProjectInformation info = ProjectInformationManager.Instance.Get(project);

            lock (info) {
                info.RemoveFileInfo(filename);

                IEnumerable <string> tags = GetTags(project, filename, headers);
                if (tags == null)
                {
                    return;
                }

                foreach (string tagEntry in tags)
                {
                    if (tagEntry.StartsWith("!_"))
                    {
                        continue;
                    }

                    Tag tag = ParseTag(tagEntry);

                    if (tag != null)
                    {
                        AddInfo(info, tag, tagEntry);
                    }
                }
            }
        }
        /// <summary>
        /// Remove a file's parse information from the database.
        /// </summary>
        /// <param name="project">
        /// A <see cref="Project"/>: The project to which the file belongs.
        /// </param>
        /// <param name="filename">
        /// A <see cref="System.String"/>: The file.
        /// </param>
        public void RemoveFileInfo(Project project, string filename)
        {
            ProjectInformation info = ProjectInformationManager.Instance.Get(project);

            lock (info){ info.RemoveFileInfo(filename); }
            OnFileUpdated(new ClassPadEventArgs(project));
        }
        private void DoUpdateFileTags(Project project, string filename)
        {
            if (!DepsInstalled)
            {
                return;
            }

            string[]      headers        = Headers(project, filename, false);
            string[]      system_headers = diff(Headers(project, filename, true), headers);
            StringBuilder ctags_kinds    = new StringBuilder("--C++-kinds=+px");

            if (PropertyService.Get <bool> ("CBinding.ParseLocalVariables", true))
            {
                ctags_kinds.Append("+l");
            }

            // Maybe we should only ask for locals for 'local' files? (not external #includes?)
            ctags_kinds.AppendFormat(" --fields=+aStisk-fz --language-force=C++ --excmd=number --line-directives=yes -f - '{0}'", filename);
            foreach (string header in headers)
            {
                ctags_kinds.AppendFormat(" '{0}'", header);
            }

            string ctags_output = string.Empty;

            ProcessWrapper p = null;

            System.IO.StringWriter output = null, error = null;
            try {
                output = new System.IO.StringWriter();
                error  = new System.IO.StringWriter();

                p = Runtime.ProcessService.StartProcess("ctags", ctags_kinds.ToString(), project.BaseDirectory, output, error, null);
                p.WaitForOutput(10000);
                if (p.ExitCode != 0)
                {
                    LoggingService.LogError("Ctags did not successfully populate the tags database from '{0}' within ten seconds.\nError output: {1}", filename, error.ToString());
                    return;
                }
                ctags_output = output.ToString();
            } catch (Exception ex) {
                throw new IOException("Could not create tags database (You must have exuberant ctags installed).", ex);
            } finally {
                if (output != null)
                {
                    output.Dispose();
                }
                if (error != null)
                {
                    error.Dispose();
                }
                if (p != null)
                {
                    p.Dispose();
                }
            }

            ProjectInformation info = ProjectInformationManager.Instance.Get(project);

            lock (info) {
                info.RemoveFileInfo(filename);
                string tagEntry;

                using (StringReader reader = new StringReader(ctags_output)) {
                    while ((tagEntry = reader.ReadLine()) != null)
                    {
                        if (tagEntry.StartsWith("!_"))
                        {
                            continue;
                        }

                        Tag tag = ParseTag(tagEntry);

                        if (tag != null)
                        {
                            AddInfo(info, tag, ctags_output);
                        }
                    }
                }
            }

            OnFileUpdated(new ClassPadEventArgs(project));

            if (PropertyService.Get <bool> ("CBinding.ParseSystemTags", true))
            {
                UpdateSystemTags(project, filename, system_headers);
            }

            if (cache.Count > cache_size)
            {
                cache.Clear();
            }
        }