// /// <summary> /// We come here : After a Project load (xFile == NULL), or after a File Save (xFile == the Saved file) /// </summary> private void OnFileWalkComplete(XFile xfile) { if (xfile == null) { return; } // Retrieve the corresponding node if (!xfile.HasCode || XSolution.IsClosing) { return; } // if (xfile.Virtual) { return; } XSharpProjectNode prjNode = (XSharpProjectNode)xfile.Project.ProjectNode; Microsoft.VisualStudio.Project.HierarchyNode node = prjNode.FindURL(xfile.FullPath); if (node != null) { XSharpModuleId module = new XSharpModuleId(prjNode.InteropSafeHierarchy, node.ID); module.ContentHashCode = xfile.ContentHashCode; CreateUpdateTreeRequest(xfile.SourcePath, module); } }
/// <summary> /// Handle the deletion of a file in the Solution Hierarchy /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void OnDeleteFile(object sender, HierarchyEventArgs args) { IVsHierarchy hierarchy = sender as IVsHierarchy; if (null == hierarchy) { return; } XSharpModuleId id = new XSharpModuleId(hierarchy, args.ItemID); lock (files) { HashSet <XSharpLibraryNode> values = null; // Ok, now remove ALL nodes for that key if (files.TryGetValue(id, out values)) { foreach (XSharpLibraryNode node in values) { if (node.Freeing(id.ItemID) == 0) { if (node.parent != null) { node.parent.RemoveNode(node); } } } } // and then remove the key files.Remove(id); } // }
private void CreateMembersTree(LibraryNode current, XTypeDefinition scope, XSharpModuleId moduleId) { if (null == scope || XSolution.IsClosing) { return; } foreach (XMemberDefinition member in scope.Members) { XSharpLibraryNode newNode = new XSharpLibraryNode(member, "", moduleId.Hierarchy, moduleId.ItemID); // The classes are always added to the root node, the functions to the // current node. if ((newNode.NodeType & LibraryNode.LibraryNodeType.Members) != LibraryNode.LibraryNodeType.None) { current.AddNode(newNode); newNode.parent = current; lock (files) { files.Add(moduleId, newNode); } } } }
private void CreateParseRequest(string file, XSharpModuleId id) { LibraryTask task = new LibraryTask(file, id); task.ModuleID = id; lock (requests) { requests.Enqueue(task); } requestPresent.Set(); }
public void Dispose() { if ((null != connectionPoint) && (0 != connectionCookie)) { connectionPoint.Unadvise(connectionCookie); System.Diagnostics.Debug.WriteLine("\n\tUnadvised from TextLinesEvents\n"); } connectionCookie = 0; connectionPoint = null; this.buffer = null; this.fileId = null; }
public override bool Equals(object obj) { XSharpModuleId other = obj as XSharpModuleId; if (null == obj) { return(false); } if (!ownerHierarchy.Equals(other.ownerHierarchy)) { return(false); } return(itemId == other.itemId); }
public TextLineEventListener(IVsTextLines buffer, string fileName, XSharpModuleId id) { this.buffer = buffer; this.fileId = id; this.fileName = fileName; IConnectionPointContainer container = buffer as IConnectionPointContainer; if (null != container) { Guid eventsGuid = typeof(IVsTextLinesEvents).GUID; container.FindConnectionPoint(ref eventsGuid, out connectionPoint); connectionPoint.Advise(this as IVsTextLinesEvents, out connectionCookie); } }
private void CreateUpdateTreeRequest(string file, XSharpModuleId id) { if (XSolution.IsClosing) { return; } LibraryTask task = new LibraryTask(file, id); task.ModuleID = id; lock (requests) { requests.Enqueue(task); } requestPresent.Set(); }
private void CreateGlobalTree(LibraryNode current, XTypeDefinition scope, XSharpModuleId moduleId) { if (null == scope || XSolution.IsClosing) { return; } foreach (XMemberDefinition member in scope.XMembers) { XSharpLibraryNode newNode = new XSharpLibraryNode(member, "", moduleId.Hierarchy, moduleId.ItemID); // Functions ? if ((newNode.NodeType & LibraryNode.LibraryNodeType.Members) != LibraryNode.LibraryNodeType.None) { current.AddNode(newNode); newNode.parent = current; lock (files) { files.Add(moduleId, newNode); } } } }
public int OnBeforeDocumentWindowShow(uint docCookie, int fFirstShow, IVsWindowFrame pFrame) { #if TEXTCHANGELISTENER // Check if this document is in the list of the documents. if (documents.ContainsKey(docCookie)) { return(VSConstants.S_OK); } // Get the information about this document from the RDT. IVsRunningDocumentTable rdt = provider.GetService(typeof(SVsRunningDocumentTable)) as IVsRunningDocumentTable; if (null != rdt) { // Note that here we don't want to throw in case of error. uint flags; uint readLocks; uint writeLoks; string documentMoniker; IVsHierarchy hierarchy; uint itemId; IntPtr unkDocData; int hr = rdt.GetDocumentInfo(docCookie, out flags, out readLocks, out writeLoks, out documentMoniker, out hierarchy, out itemId, out unkDocData); try { if (Microsoft.VisualStudio.ErrorHandler.Failed(hr) || (IntPtr.Zero == unkDocData)) { return(VSConstants.S_OK); } // Check if the hierarchy is one of the hierarchies this service is monitoring. if (!hierarchies.ContainsKey(hierarchy)) { // This hierarchy is not monitored, we can exit now. return(VSConstants.S_OK); } // Check the extension of the file to see if a listener is required. string extension = System.IO.Path.GetExtension(documentMoniker); if (0 != string.Compare(extension, ".prg", StringComparison.OrdinalIgnoreCase)) { return(VSConstants.S_OK); } // Create the module id for this document. XSharpModuleId docId = new XSharpModuleId(hierarchy, itemId); // Try to get the text buffer. IVsTextLines buffer = Marshal.GetObjectForIUnknown(unkDocData) as IVsTextLines; // Create the listener. // So we are informed in case of Buffer change //TextLineEventListener listener = new TextLineEventListener(buffer, documentMoniker, docId); // Set the event handler for the change event. Note that there is no difference // between the AddFile and FileChanged operation, so we can use the same handler. //listener.OnFileChanged += new EventHandler<HierarchyEventArgs>(OnNewFile); // Add the listener to the dictionary, so we will not create it anymore. //documents.Add(docCookie, listener); } finally { if (IntPtr.Zero != unkDocData) { Marshal.Release(unkDocData); } } } // Always return success. #endif return(VSConstants.S_OK); }
//private object _sourceLock; public LibraryTask(string fileName, XSharpModuleId ModuleID) { this.fileName = fileName; this.moduleId = ModuleID; //this.text = text; }
private void CreateModuleTree(XSharpLibraryProject prjNode, XFile scope, XSharpModuleId moduleId) { if (null == scope || XSolution.IsClosing) { return; } if (!scope.HasCode) { return; } // Retrieve all Types // !!! WARNING !!! The XFile object (scope) comes from the DataBase // We should retrieve TypeList from the DataBase..... var namespaces = XSharpModel.XDatabase.GetNamespacesInFile(scope.Id.ToString()); if (namespaces == null) { return; } // var elements = XDbResultHelpers.BuildTypesInFile(scope, namespaces); // First search for NameSpaces foreach (XTypeDefinition xType in elements) { if (xType.Kind == Kind.Namespace) { // Does that NameSpace already exist ? // Search for the corresponding NameSpace XSharpLibraryNode newNode; LibraryNode nsNode = prjNode.SearchNameSpace(xType.Name); if (nsNode is XSharpLibraryNode) { newNode = (XSharpLibraryNode)nsNode; newNode.Depends(moduleId.ItemID); } else { newNode = new XSharpLibraryNode(xType, "", moduleId.Hierarchy, moduleId.ItemID); // NameSpaces are always added to the root. prjNode.AddNode(newNode); newNode.parent = prjNode; } // Handle Global Scope here // It contains Function/Procedure/etc... if (newNode.Name == "(Global Scope)") { CreateGlobalTree(newNode, xType, moduleId); } lock (files) { files.Add(moduleId, newNode); } } } // Retrieve Classes from the file var types = XSharpModel.XDatabase.GetTypesInFile(scope.Id.ToString()); if (types == null) { return; } elements = XDbResultHelpers.BuildFullTypesInFile(scope, types); // Now, look for Classes foreach (XTypeDefinition xType in elements) { // Is it a kind of Type ? if ((xType.Kind.IsType())) { string nSpace = prjNode.DefaultNameSpace; if (!String.IsNullOrEmpty(xType.Namespace)) { nSpace = xType.Namespace; } // Search for the corresponding NameSpace LibraryNode nsNode = prjNode.SearchNameSpace(nSpace); if (nsNode == null) { nsNode = prjNode.SearchClass(nSpace); } if (nsNode is XSharpLibraryNode) { XSharpLibraryNode xsNSNode = (XSharpLibraryNode)nsNode; // So the Class node will belong to that NameSpace Node // Now, try to check if such Type already exist XSharpLibraryNode newNode; LibraryNode newTmpNode; newTmpNode = xsNSNode.SearchClass(xType.Name); if (newTmpNode is XSharpLibraryNode) { newNode = (XSharpLibraryNode)newTmpNode; newNode.Depends(moduleId.ItemID); } else { newNode = new XSharpLibraryNode(xType, "", moduleId.Hierarchy, moduleId.ItemID); nsNode.AddNode(newNode); newNode.parent = nsNode; } // // Insert Members CreateMembersTree(newNode, xType, moduleId); // lock (files) { files.Add(moduleId, newNode); } } else { // Not found !? } } } }
/// <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 UpdateTreeThread() { 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 (waitResult == 1) { // The shutdown of this component is started, so exit the thread. return; } if (waitResult == WaitHandle.WaitTimeout) { continue; } // LibraryTask task = null; lock (requests) { if (0 != requests.Count) { task = requests.Dequeue(); } if (0 == requests.Count) { requestPresent.Reset(); } } if (null == task) { continue; } // XFile scope = null; if (System.IO.File.Exists(task.FileName)) { scope = XSharpModel.XSolution.FindFile(task.FileName); if (scope == null || (!scope.HasCode)) { continue; } } // If the file already exist lock (files) { // These are the existing Modules XSharpModuleId[] aTmp = new XSharpModuleId[files.Keys.Count]; files.Keys.CopyTo(aTmp, 0); // Does this module already exist ? XSharpModuleId found = Array.Find <XSharpModuleId>(aTmp, (x => x.Equals(task.ModuleID))); if (found != null) { // Doesn't it have the same members? if (found.ContentHashCode == task.ModuleID.ContentHashCode) { continue; } // HashSet <XSharpLibraryNode> values = null; // Ok, now remove ALL nodes for that key if (files.TryGetValue(task.ModuleID, out values)) { foreach (XSharpLibraryNode node in values) { if (node.Freeing(task.ModuleID.ItemID) == 0) { if (node.parent != null) { node.parent.RemoveNode(node); } } } // and then remove the key files.Remove(task.ModuleID); } } // LibraryNode prjNode = this.library.SearchHierarchy(task.ModuleID.Hierarchy); if (prjNode is XSharpLibraryProject) { // CreateModuleTree((XSharpLibraryProject)prjNode, scope, task.ModuleID); // prjNode.updateCount += 1; //this.prjNode.AddNode(node); //library.AddNode(node); this.library.Refresh(); } } } }
public void UnregisterHierarchy(IVsHierarchy hierarchy) { if ((null == hierarchy) || !hierarchies.ContainsKey(hierarchy)) { return; } // Retrieve the listener for that Tree/Hierarchy HierarchyListener listener = hierarchies[hierarchy]; if (null != listener) { listener.Dispose(); } hierarchies.Remove(hierarchy); if (0 == hierarchies.Count) { UnregisterRDTEvents(); } // Now remove all nodes // for all files lock (files) { XSharpModuleId[] keys = new XSharpModuleId[files.Keys.Count]; // Get all Keys (ModuleId) files.Keys.CopyTo(keys, 0); foreach (XSharpModuleId id in keys) { // The file is owned by the Hierarchy ? if (hierarchy.Equals(id.Hierarchy)) { HashSet <XSharpLibraryNode> values = null; // Ok, now remove ALL nodes for that key if (files.TryGetValue(id, out values)) { foreach (XSharpLibraryNode node in values) { if (node.parent != null) { node.parent.RemoveNode(node); } } } // and then remove the key files.Remove(id); } } } // LibraryNode prjNode = this.library.SearchHierarchy(hierarchy); if (prjNode is XSharpLibraryProject) { library.RemoveNode(prjNode); } #if TEXTCHANGELISTENER // Remove the document listeners. uint[] docKeys = new uint[documents.Keys.Count]; documents.Keys.CopyTo(docKeys, 0); foreach (uint id in docKeys) { TextLineEventListener docListener = documents[id]; if (hierarchy.Equals(docListener.FileID.Hierarchy)) { documents.Remove(id); docListener.Dispose(); } } #endif }
private void CreateGlobalTree(LibraryNode globalScope, IList <XMemberDefinition> XMembers, XSharpModuleId moduleId) { if (XSolution.IsClosing) { return; } foreach (XMemberDefinition member in XMembers) { XSharpLibraryNode newNode = new XSharpLibraryNode(member, "", moduleId.Hierarchy, moduleId.ItemID); // Functions ? if ((newNode.NodeType & LibraryNode.LibraryNodeType.Members) != LibraryNode.LibraryNodeType.None) { globalScope.AddNode(newNode); newNode.parent = globalScope; lock (files) { files.Add(moduleId, newNode); } } } }
private void CreateModuleTree(XSharpLibraryProject prjNode, XFile scope, XSharpModuleId moduleId) { if ((null == scope)) { return; } if (!scope.HasCode) { return; } // Retrieve all Types var elements = scope.TypeList; if (elements == null) { return; } // // First search for NameSpaces foreach (KeyValuePair <string, XType> pair in elements) { XType xType = pair.Value; if (xType.Kind == Kind.Namespace) { // Does that NameSpave already exist ? // Search for the corresponding NameSpace XSharpLibraryNode newNode; LibraryNode nsNode = prjNode.SearchNameSpace(xType.Name); if (nsNode is XSharpLibraryNode) { newNode = (XSharpLibraryNode)nsNode; newNode.Depends(moduleId.ItemID); } else { newNode = new XSharpLibraryNode(xType, "", moduleId.Hierarchy, moduleId.ItemID); // NameSpaces are always added to the root. prjNode.AddNode(newNode); newNode.parent = prjNode; } // Handle Global Scope here // It contains Function/Procedure/etc... if (newNode.Name == "(Global Scope)") { CreateGlobalTree(newNode, xType, moduleId); } lock (files) { files.Add(moduleId, newNode); } } } // Now, look for Classes foreach (KeyValuePair <string, XType> pair in elements) { XType xType = pair.Value; // Is it a kind of Type ? if ((xType.Kind.IsType())) { string nSpace = prjNode.DefaultNameSpace; if (!String.IsNullOrEmpty(xType.NameSpace)) { nSpace = xType.NameSpace; } // Search for the corresponding NameSpace LibraryNode nsNode = prjNode.SearchNameSpace(nSpace); if (nsNode is XSharpLibraryNode) { XSharpLibraryNode xsNSNode = (XSharpLibraryNode)nsNode; // So the Class node will belong to that NameSpace Node // Now, try to check if such Type already exist XSharpLibraryNode newNode; LibraryNode newTmpNode; newTmpNode = xsNSNode.SearchClass(xType.Name); if (newTmpNode is XSharpLibraryNode) { newNode = (XSharpLibraryNode)newTmpNode; newNode.Depends(moduleId.ItemID); } else { newNode = new XSharpLibraryNode(xType, "", moduleId.Hierarchy, moduleId.ItemID); nsNode.AddNode(newNode); newNode.parent = nsNode; } // Insert Members CreateMembersTree(newNode, xType, moduleId); // lock (files) { files.Add(moduleId, newNode); } } else { // Not found !? } } } }