protected override void OnNewFile(LibraryTask task) { IProjectEntry item; if (task.TextBuffer != null) { item = task.TextBuffer.GetAnalysis(); } else { item = task.ModuleID.Hierarchy.GetProject().GetJProject().GetAnalyzer().AnalyzeFile(task.FileName); } IJProjectEntry pyCode; if (item != null && (pyCode = item as IJProjectEntry) != null) { // We subscribe to OnNewAnalysis here instead of OnNewParseTree so that // in the future we can use the analysis to include type information in the // object browser (for example we could include base type information with // links elsewhere in the object browser). pyCode.OnNewAnalysis += (sender, args) => { FileParsed(task, new AstScopeNode(pyCode.Tree, pyCode)); }; } }
/// <summary> /// Overridden in the base class to receive notifications of when a file should /// be analyzed for inclusion in the library. The derived class should queue /// the parsing of the file and when it's complete it should call FileParsed /// with the provided LibraryTask and an IScopeNode which provides information /// about the members of the file. /// </summary> protected virtual void OnNewFile(LibraryTask task) { }
/// <summary> /// Called by derived class when a file has been parsed. The caller should /// provide the LibraryTask received from the OnNewFile call and an IScopeNode /// which represents the contents of the library. /// /// It is safe to call this method from any thread. /// </summary> protected void FileParsed(LibraryTask task, IScopeNode scope) { try { var project = task.ModuleID.Hierarchy.GetProject().GetCommonProject(); HierarchyNode fileNode = fileNode = project.NodeFromItemId(task.ModuleID.ItemID); if (fileNode == null) { return; } LibraryNode module = CreateFileLibraryNode( fileNode, System.IO.Path.GetFileName(task.FileName), task.FileName, LibraryNodeType.PhysicalContainer ); // TODO: Creating the module tree should be done lazily as needed // Currently we replace the entire tree and rely upon the libraries // update count to invalidate the whole thing. We could do this // finer grained and only update the changed nodes. But then we // need to make sure we're not mutating lists which are handed out. CreateModuleTree(module, module, scope, task.FileName + ":", 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); } } } catch (COMException) { // we're shutting down and can't get the project } }