コード例 #1
0
 internal CocoLibraryNode(CocoLibraryNode node) :
     base(node)
 {
     this.fileId         = node.fileId;
     this.ownerHierarchy = node.ownerHierarchy;
     this.fileMoniker    = node.fileMoniker;
     this.sourceSpan     = node.sourceSpan;
 }
コード例 #2
0
 private void CreateLibraryEntry(LibraryNode parent, ModuleId moduleId, IEnumerable <AddTokenInfo> tokens, IDictionary <string, List <AddTokenInfo> > references)
 {
     foreach (AddTokenInfo info in tokens)
     {
         int             length = info.Name == null ? 0 : info.Name.Length;
         CocoLibraryNode entry  = new CocoLibraryNode(info.Name, info.Line, info.Col, info.Col + length, moduleId.Hierarchy, moduleId.ItemID, LibraryNode.LibraryNodeType.Members);
         parent.AddNode(entry);
         if (references.ContainsKey(info.Name))
         {
             foreach (AddTokenInfo refInfo in references[info.Name])
             {
                 if (refInfo.Line == info.Line && refInfo.Col == info.Col)
                 {
                     continue; //sometimes the definition is also tracked as reference (only with tokendecls, but changes to original parser would be necessary to avoid this) -> simply skip it here
                 }
                 //it is important that the name is starts with the same name as the definition, followed by a whitespace (easy search-algorithm)
                 string          refName   = String.Format("{0} ({1}, {2}): {3}", refInfo.Name, refInfo.Line, refInfo.Col, refInfo.AdditionalInfo);
                 CocoLibraryNode reference = new CocoLibraryNode(refName, refInfo.Line, refInfo.Col, refInfo.Col + length, moduleId.Hierarchy, moduleId.ItemID, LibraryNode.LibraryNodeType.References);
                 reference.Visible = false;
                 parent.AddNode(reference);
             }
         }
     }
 }
コード例 #3
0
        public int GetList2(uint ListType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch, out IVsSimpleObjectList2 ppIVsSimpleObjectList2)
        {
            //the find-references command is implemented in this method
            //because it is not documented what exactly has to be implemented, we perform the search on our own (see CocoViewFilter - the request is initialized in there)
            if (((_LIB_LISTFLAGS)flags & _LIB_LISTFLAGS.LLF_USESEARCHFILTER) != 0 && pobSrch != null && pobSrch.Length > 0)
            {
                //when not filtering for members, the same list will be displayed three times (this is the same in the IrconPython sample of VS SDK 2008), so we handled it in the way to only support filtering for members (no namespaces, no hierarchys)
                if ((_LIB_LISTTYPE)ListType != _LIB_LISTTYPE.LLT_MEMBERS)
                {
                    //we just provide filter for members (not for namespaces, hierarchies, etc.)
                    ppIVsSimpleObjectList2 = null;
                    return(VSConstants.S_OK);
                }
                //we only look at one search-criteria
                VSOBSEARCHCRITERIA2 criteria = pobSrch[0];

                //get the name and check if this search was initalized by us (the manually initialized 'find-references' search)
                string searchString     = criteria.szName;
                bool   isFindReferences = criteria.dwCustom == DWCUSTOM_FINDREFSEARCH;

                if (string.IsNullOrEmpty(searchString))
                {
                    ppIVsSimpleObjectList2 = root as IVsSimpleObjectList2; //don't do anything, no filter
                    return(VSConstants.S_OK);
                }

                searchString = searchString.ToUpperInvariant();

                //references will be found by the next searchstring because references start with the same uniquename as the definition followed by a whitespace
                string searchStringWithSpace = searchString + " ";

                //copy will be returned
                LibraryNode classLevelCopy = new LibraryNode(classLevelNode);

                for (int i = 0; i < classLevelCopy.children.Count; i++)
                {
                    //copy the node, because we have to modify it
                    CocoLibraryNode fileCopy = new CocoLibraryNode(classLevelCopy.children[i] as CocoLibraryNode);

                    for (int j = 0; j < fileCopy.children.Count; j++)
                    {
                        if (isFindReferences)   //search for exact member name and for references
                        {
                            if ((fileCopy.children[j].NodeType == LibraryNode.LibraryNodeType.Members && fileCopy.children[j].UniqueName.ToUpperInvariant() == searchString) ||
                                fileCopy.children[j].NodeType == LibraryNode.LibraryNodeType.References && fileCopy.children[j].UniqueName.ToUpperInvariant().StartsWith(searchStringWithSpace))
                            {
                                fileCopy.children[j]         = new CocoLibraryNode(fileCopy.children[j] as CocoLibraryNode); //make a copy and make that visible
                                fileCopy.children[j].Visible = true;
                            }
                            else
                            {
                                fileCopy.RemoveNode(fileCopy.children[j]);
                                j--;
                            }
                        }
                        else   //don't search for references, jsut for members which contain the search string
                        {
                            if (fileCopy.children[j].NodeType == LibraryNode.LibraryNodeType.Members && fileCopy.children[j].UniqueName.ToUpperInvariant().Contains(searchString))
                            {
                                fileCopy.children[j]         = new CocoLibraryNode(fileCopy.children[j] as CocoLibraryNode); //make a copy and make that visible
                                fileCopy.children[j].Visible = true;
                            }
                            else
                            {
                                fileCopy.RemoveNode(fileCopy.children[j]);
                                j--;
                            }
                        }
                    }

                    //if the current file doesn't contain and result, remove it
                    if (fileCopy.children.Count <= 0)
                    {
                        classLevelCopy.RemoveNode(classLevelCopy.children[i]);
                        i--;
                    }
                    else
                    {
                        classLevelCopy.children[i] = fileCopy; //assign the modified copy
                    }
                }

                //move search results to top-level (now they are on file-level, but search results have to be displayed at very top level)
                System.Collections.Generic.List <LibraryNode> children;

                if (classLevelCopy.children.Count > 0)
                {
                    if (classLevelCopy.children.Count == 1)
                    {
                        children = classLevelCopy.children[0].children; //this is the normal path (and the very fast one), because normally there is only one atg-file in a project
                    }
                    else                                                //more than one
                    {
                        children = new System.Collections.Generic.List <LibraryNode>();
                        for (int i = 0; i < classLevelCopy.children.Count; i++)
                        {
                            children.AddRange(classLevelCopy.children[i].children);
                        }
                    }
                    classLevelCopy.children = children;
                }

                //return the modifed copy as result
                ppIVsSimpleObjectList2 = classLevelCopy as IVsSimpleObjectList2;
                return(VSConstants.S_OK);
            }

            ppIVsSimpleObjectList2 = root as IVsSimpleObjectList2;
            return(VSConstants.S_OK);
        }
コード例 #4
0
        /// <summary>
        /// Main function of the parsing thread.
        /// This function waits on the queue of the parsing requests and build the parsing tree for
        /// a specific file. The resulting tree is built using LibraryNode objects so that it can
        /// be used inside the class view or object browser.
        /// </summary>
        private void ParseThread()
        {
            const int waitTimeout = 500;

            // Define the array of events this function is interest in.
            WaitHandle[] eventsToWait = new WaitHandle[] { requestPresent, shutDownStarted };
            // Execute the tasks.
            while (true)
            {
                // Wait for a task or a shutdown request.
                int waitResult = WaitHandle.WaitAny(eventsToWait, waitTimeout, false);
                if (1 == waitResult)
                {
                    // The shutdown of this component is started, so exit the thread.
                    return;
                }
                LibraryTask task = null;
                lock (requests) {
                    if (0 != requests.Count)
                    {
                        task = requests.Dequeue();
                    }
                    if (0 == requests.Count)
                    {
                        requestPresent.Reset();
                    }
                }
                if (null == task)
                {
                    continue;
                }

                string sourceText = task.Text;
                if (sourceText == null)
                {
                    //should not happen, but to be robust
                    if (!System.IO.File.Exists(task.FileName))
                    {
                        continue;
                    }

                    //read file content as string
                    try {
                        using (System.IO.StreamReader sr = System.IO.File.OpenText(task.FileName)) {
                            sourceText = sr.ReadToEnd();
                        }
                    }
                    catch (Exception ex) {
                        System.Diagnostics.Trace.WriteLine(String.Format("Error when parsing file '{0}': {1}\n{2}", task.FileName, ex.Message, ex.StackTrace));
                        continue;
                    }
                }

                if (string.IsNullOrEmpty(sourceText))
                {
                    continue;
                }

                CocoParserProxy.CocoParseResult result = CocoParserProxy.Parse(sourceText, task.FileName);

                //maybe use coco-library entry (to avoid not-implemented exception in librarynode.getcategory2)
                CocoLibraryNode module = new CocoLibraryNode(
                    System.IO.Path.GetFileName(task.FileName),
                    1,
                    1,
                    1,
                    task.ModuleID.Hierarchy,
                    task.ModuleID.ItemID,
                    LibraryNode.LibraryNodeType.Classes);


                CreateLibraryEntry(module, result, task.ModuleID);

                if (null != task.ModuleID)
                {
                    LibraryNode previousItem = null;
                    lock (files) {
                        if (files.TryGetValue(task.ModuleID, out previousItem))
                        {
                            files.Remove(task.ModuleID);
                        }
                    }
                    library.RemoveNode(previousItem);
                }
                library.AddNode(module);
                if (null != task.ModuleID)
                {
                    lock (files) {
                        files.Add(task.ModuleID, module);
                    }
                }
            }
        }