Exemple #1
0
        /* Function: CreateLanguageEntry
         * Creates an entry for the language, adds it to the class menu, and returns it.  It will also create the <rootClassMenu>
         * container if necessary.
         */
        protected MenuEntries.Language CreateLanguageEntry(Languages.Language language)
        {
                        #if DEBUG
            if (FindLanguageEntry(language) != null)
            {
                throw new Exception("Tried to create a language entry that already existed in the menu.");
            }
                        #endif

            if (rootClassMenu == null)
            {
                rootClassMenu       = new MenuEntries.Container(Hierarchy.Class);
                rootClassMenu.Title = Engine.Locale.Get("NaturalDocs.Engine", "Menu.Classes");
            }

            MenuEntries.Language languageEntry = new MenuEntries.Language(language, Hierarchy.Class);
            languageEntry.Parent = rootClassMenu;
            rootClassMenu.Members.Add(languageEntry);

            return(languageEntry);
        }
Exemple #2
0
        /* Function: CreateFileSourceEntry
         * Creates an entry for the file source, adds it to the menu, and returns it.  It will also create the <rootFileMenu>
         * container if necessary.
         */
        protected MenuEntries.FileSource CreateFileSourceEntry(Files.FileSource fileSource)
        {
                        #if DEBUG
            if (FindFileSourceEntry(fileSource) != null)
            {
                throw new Exception("Tried to create a file source entry that already existed in the menu.");
            }
                        #endif

            if (rootFileMenu == null)
            {
                rootFileMenu       = new MenuEntries.Container(Hierarchy.File);
                rootFileMenu.Title = Engine.Locale.Get("NaturalDocs.Engine", "Menu.Files");
            }

            MenuEntries.FileSource fileSourceEntry = new MenuEntries.FileSource(fileSource);
            fileSourceEntry.Parent = rootFileMenu;
            rootFileMenu.Members.Add(fileSourceEntry);

            return(fileSourceEntry);
        }
Exemple #3
0
        /* Function: AddFile
         * Adds a file to the menu tree.
         */
        public void AddFile(Files.File file)
        {
                        #if DEBUG
            if (isCondensed)
            {
                throw new Exception("Cannot add a file to the menu once it's been condensed.");
            }
                        #endif


            // Find which file source owns this file and generate a relative path to it.

            MenuEntries.FileSource fileSourceEntry = FindOrCreateFileSourceEntryOf(file);
            Path relativePath = fileSourceEntry.WrappedFileSource.MakeRelative(file.FileName);


            // Split off the file name and split the rest into individual folder names.

            string        prefix;
            List <string> pathSegments;
            relativePath.Split(out prefix, out pathSegments);

            string fileName = pathSegments[pathSegments.Count - 1];
            pathSegments.RemoveAt(pathSegments.Count - 1);


            // Create the file entry and find out where it goes.  Create new folder levels as necessary.

            MenuEntries.File      fileEntry = new MenuEntries.File(file);
            MenuEntries.Container container = fileSourceEntry;

            foreach (string pathSegment in pathSegments)
            {
                Path pathFromFileSource;

                if (container == fileSourceEntry)
                {
                    pathFromFileSource = pathSegment;
                }
                else
                {
                    pathFromFileSource = (container as MenuEntries.Folder).PathFromFileSource + '/' + pathSegment;
                }

                MenuEntries.Folder folderEntry = null;

                foreach (var member in container.Members)
                {
                    if (member is MenuEntries.Folder &&
                        (member as MenuEntries.Folder).PathFromFileSource == pathFromFileSource)
                    {
                        folderEntry = (MenuEntries.Folder)member;
                        break;
                    }
                }

                if (folderEntry == null)
                {
                    folderEntry        = new MenuEntries.Folder(pathFromFileSource);
                    folderEntry.Parent = container;
                    container.Members.Add(folderEntry);
                }

                container = folderEntry;
            }

            fileEntry.Parent = container;
            container.Members.Add(fileEntry);
        }
Exemple #4
0
        /* Function: AddClass
         * Adds a class to the menu tree.
         */
        public void AddClass(Symbols.ClassString classString)
        {
                        #if DEBUG
            if (isCondensed)
            {
                throw new Exception("Cannot add a class to the menu once it's been condensed.");
            }
                        #endif


            string[] classSegments = classString.Symbol.SplitSegments();

            MenuEntries.Container container;
            bool ignoreCase;

            if (classString.Hierarchy == Hierarchy.Class)
            {
                MenuEntries.Language languageEntry = FindOrCreateLanguageEntryOf(classString);

                container  = languageEntry;
                ignoreCase = (languageEntry.WrappedLanguage.CaseSensitive == false);
            }

            else if (classString.Hierarchy == Hierarchy.Database)
            {
                if (rootDatabaseMenu == null)
                {
                    rootDatabaseMenu       = new MenuEntries.Container(Hierarchy.Database);
                    rootDatabaseMenu.Title = Engine.Locale.Get("NaturalDocs.Engine", "Menu.Database");
                }

                container  = rootDatabaseMenu;
                ignoreCase = true;
            }

            else
            {
                throw new NotImplementedException();
            }


            // Create the class and find out where it goes.  Create new scope containers as necessary.

            MenuEntries.Class classEntry = new MenuEntries.Class(classString);
            string            scopeSoFar = null;

            // We only want to walk through the scope levels so we use length - 1 to ignore the last segment, which is the class name.
            for (int i = 0; i < classSegments.Length - 1; i++)
            {
                string classSegment = classSegments[i];

                if (scopeSoFar == null)
                {
                    scopeSoFar = classSegment;
                }
                else
                {
                    scopeSoFar += Symbols.SymbolString.SeparatorChar + classSegment;
                }

                MenuEntries.Scope scopeEntry = null;

                foreach (var member in container.Members)
                {
                    if (member is MenuEntries.Scope &&
                        string.Compare((member as MenuEntries.Scope).WrappedScopeString, scopeSoFar, ignoreCase) == 0)
                    {
                        scopeEntry = (MenuEntries.Scope)member;
                        break;
                    }
                }

                if (scopeEntry == null)
                {
                    scopeEntry        = new MenuEntries.Scope(Symbols.SymbolString.FromExportedString(scopeSoFar), classString.Hierarchy);
                    scopeEntry.Parent = container;
                    container.Members.Add(scopeEntry);
                }

                container = scopeEntry;
            }

            classEntry.Parent = container;
            container.Members.Add(classEntry);
        }
Exemple #5
0
        /* Function: ConvertToJSON
         * Converts a Container menu entry to JSON, along with all of its members.  This is a recursive function so it will convert
         * the entire tree inside the container.
         */
        protected JSONMenuEntries.Container ConvertToJSON(MenuEntries.Container menuContainer)
        {
            JSONMenuEntries.Container jsonContainer     = new JSONMenuEntries.Container(menuContainer);
            StringBuilder             jsonBeforeMembers = new StringBuilder();

            jsonBeforeMembers.Append("[2,");


            // Title

            if (menuContainer.CondensedTitles == null)
            {
                if (menuContainer.Title != null)
                {
                    jsonBeforeMembers.Append('"');
                    jsonBeforeMembers.StringEscapeAndAppend(menuContainer.Title.ToHTML());
                    jsonBeforeMembers.Append('"');
                }
                // Otherwise leave an empty space before the comma.  We don't have to write out "undefined".
            }
            else
            {
                jsonBeforeMembers.Append("[\"");
                jsonBeforeMembers.StringEscapeAndAppend(menuContainer.Title.ToHTML());
                jsonBeforeMembers.Append('"');

                foreach (string condensedTitle in menuContainer.CondensedTitles)
                {
                    jsonBeforeMembers.Append(",\"");
                    jsonBeforeMembers.StringEscapeAndAppend(condensedTitle.ToHTML());
                    jsonBeforeMembers.Append('"');
                }

                jsonBeforeMembers.Append(']');
            }


            // Hash path

            jsonBeforeMembers.Append(',');

            string hashPath = null;

            if (menuContainer is MenuEntries.FileSource)
            {
                var fileSourceEntry = (MenuEntries.FileSource)menuContainer;
                hashPath = Paths.SourceFile.FolderHashPath(fileSourceEntry.WrappedFileSource.Number,
                                                           fileSourceEntry.CondensedPathFromFileSource);
            }

            else if (menuContainer is MenuEntries.Folder)
            {
                var folderEntry = (MenuEntries.Folder)menuContainer;

                // Walk up the tree until you find the FileSource
                MenuEntries.Container parentEntry = menuContainer.Parent;

                                #if DEBUG
                if (parentEntry == null)
                {
                    throw new Exception("Parent must be defined when generating JSON for menu folder \"" + (folderEntry.Title ?? "") + "\".");
                }
                                #endif

                while ((parentEntry is MenuEntries.FileSource) == false)
                {
                    parentEntry = parentEntry.Parent;

                                        #if DEBUG
                    if (parentEntry == null)
                    {
                        throw new Exception("Couldn't find a file source among the folder \"" + (folderEntry.Title ?? "") + "\"'s parents when generating JSON.");
                    }
                                        #endif
                }

                var fileSourceEntry = (MenuEntries.FileSource)parentEntry;
                hashPath = Paths.SourceFile.FolderHashPath(fileSourceEntry.WrappedFileSource.Number,
                                                           folderEntry.PathFromFileSource);
            }

            else if (menuContainer is MenuEntries.Language)
            {
                var languageEntry = (MenuEntries.Language)menuContainer;
                hashPath = Paths.Class.QualifierHashPath(languageEntry.WrappedLanguage.SimpleIdentifier,
                                                         languageEntry.CondensedScopeString);
            }

            else if (menuContainer is MenuEntries.Scope)
            {
                var scopeEntry = (MenuEntries.Scope)menuContainer;

                if (scopeEntry.Hierarchy == Hierarchy.Class)
                {
                    // Walk up the tree until you find the language
                    MenuEntries.Container parentEntry = menuContainer.Parent;

                                        #if DEBUG
                    if (parentEntry == null)
                    {
                        throw new Exception("Parent must be defined when generating JSON for menu scope \"" + (scopeEntry.Title ?? "") + "\".");
                    }
                                        #endif

                    while ((parentEntry is MenuEntries.Language) == false)
                    {
                        parentEntry = parentEntry.Parent;

                                                #if DEBUG
                        if (parentEntry == null)
                        {
                            throw new Exception("Couldn't find a language among the scope \"" + (scopeEntry.Title ?? "") + "\"'s parents when generating JSON.");
                        }
                                                #endif
                    }

                    var languageEntry = (MenuEntries.Language)parentEntry;
                    hashPath = Paths.Class.QualifierHashPath(languageEntry.WrappedLanguage.SimpleIdentifier,
                                                             scopeEntry.WrappedScopeString);
                }
                else if (scopeEntry.Hierarchy == Hierarchy.Database)
                {
                    hashPath = Paths.Database.QualifierHashPath(scopeEntry.WrappedScopeString);
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            // If we're at one of the menu roots
            else if (menuContainer.Parent == null)
            {
                if (menuContainer.Hierarchy == Hierarchy.File || menuContainer.Hierarchy == Hierarchy.Class)
                {
                    // If we're at a root file or class container that is not also a language or file source, it means there are multiple
                    // languages and/or file sources beneath it and thus there is no shared hash path.  "CSharpClass:" and "PerlClass:",
                    // "Files:" and "Files2:", etc.
                    hashPath = null;
                }
                else if (menuContainer.Hierarchy == Hierarchy.Database)
                {
                    // If we're at the root database menu and the entry is not also a scope, it means there are multiple scopes beneath it.
                    // However, unlike files and classes, there is still the shared "Database:" hash path.
                    hashPath = Paths.Database.QualifierHashPath();
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            else
            {
                throw new NotImplementedException();
            }


            if (hashPath != null)
            {
                jsonBeforeMembers.Append('"');
                jsonBeforeMembers.StringEscapeAndAppend(hashPath);
                jsonBeforeMembers.Append('"');
            }
            // Otherwise leave an empty space before the comma.  We don't have to write out "undefined".

            jsonBeforeMembers.Append(',');

            jsonContainer.JSONBeforeMembers = jsonBeforeMembers.ToString();
            jsonContainer.JSONAfterMembers  = "]";
            jsonContainer.HashPath          = hashPath;


            // Now recurse into members

            foreach (var member in menuContainer.Members)
            {
                jsonContainer.Members.Add(ConvertToJSON(member, jsonContainer.HashPath));
            }

            return(jsonContainer);
        }