private void UnloadComReference(Reference reference, IReadOnlyList <VBProject> projects) { var referencedProjectId = GetReferenceProjectId(reference, projects); ReferencePriorityMap map = null; foreach (var item in _projectReferences) { if (item.ReferencedProjectId == referencedProjectId) { map = map != null ? null : item; } } if (map == null || !map.IsLoaded) { // we're removing a reference we weren't tracking? ...this shouldn't happen. Debug.Assert(false); return; } map.Remove(referencedProjectId); if (map.Count == 0) { _projectReferences.Remove(map); State.RemoveBuiltInDeclarations(reference); } }
private void UnloadComReference(IReference reference, IReadOnlyList <IVBProject> projects) { var referencedProjectId = GetReferenceProjectId(reference, projects); ReferencePriorityMap map = null; try { map = _projectReferences.SingleOrDefault(item => item.ReferencedProjectId == referencedProjectId); } catch (InvalidOperationException exception) { //There are multiple maps with the same referencedProjectId. That should not happen. (ghost?). Logger.Error(exception, "Failed To unload com reference with referencedProjectID {0} because RD stores multiple instances of it.", referencedProjectId); return; } if (map == null || !map.IsLoaded) { // we're removing a reference we weren't tracking? ...this shouldn't happen. return; } map.Remove(referencedProjectId); if (map.Count == 0) { _projectReferences.Remove(map); State.RemoveBuiltInDeclarations(reference); } }
private List <IReference> GetReferencesToLoadAndSaveReferencePriority(IReadOnlyList <IVBProject> projects) { var referencesToLoad = new List <IReference>(); foreach (var vbProject in projects) { var projectId = QualifiedModuleName.GetProjectId(vbProject); var references = vbProject.References; // use a 'for' loop to store the order of references as a 'priority'. // reference resolver needs this to know which declaration to prioritize when a global identifier exists in multiple libraries. for (var priority = 1; priority <= references.Count; priority++) { var reference = references[priority]; if (reference.IsBroken) { continue; } // skip loading Rubberduck.tlb (GUID is defined in AssemblyInfo.cs) if (reference.Guid == "{E07C841C-14B4-4890-83E9-8C80B06DD59D}") { // todo: figure out why Rubberduck.tlb *sometimes* throws //continue; } var referencedProjectId = GetReferenceProjectId(reference, projects); var map = _projectReferences.FirstOrDefault(item => item.ReferencedProjectId == referencedProjectId); if (map == null) { map = new ReferencePriorityMap(referencedProjectId) { { projectId, priority } }; _projectReferences.Add(map); } else { map[projectId] = priority; } if (!map.IsLoaded) { referencesToLoad.Add(reference); map.IsLoaded = true; } } } return(referencesToLoad); }
private void SyncComReferences(IReadOnlyList <VBProject> projects) { foreach (var vbProject in projects) { var projectId = QualifiedModuleName.GetProjectId(vbProject); // use a 'for' loop to store the order of references as a 'priority'. // reference resolver needs this to know which declaration to prioritize when a global identifier exists in multiple libraries. for (var priority = 1; priority <= vbProject.References.Count; priority++) { var reference = vbProject.References.Item(priority); var referencedProjectId = GetReferenceProjectId(reference, projects); var map = _projectReferences.SingleOrDefault(r => r.ReferencedProjectId == referencedProjectId); if (map == null) { map = new ReferencePriorityMap(referencedProjectId) { { projectId, priority } }; _projectReferences.Add(map); } else { map[projectId] = priority; } if (!map.IsLoaded) { _state.OnStatusMessageUpdate(ParserState.LoadingReference.ToString()); var items = _comReflector.GetDeclarationsForReference(reference).ToList(); foreach (var declaration in items) { _state.AddDeclaration(declaration); } map.IsLoaded = true; } } } var mappedIds = _projectReferences.Select(map => map.ReferencedProjectId); var unmapped = projects.SelectMany(project => project.References.Cast <Reference>()) .Where(reference => !mappedIds.Contains(GetReferenceProjectId(reference, projects))); foreach (var reference in unmapped) { UnloadComReference(reference, projects); } }
private void SyncComReferences(IReadOnlyList <VBProject> projects) { var loadTasks = new List <Task>(); foreach (var vbProject in projects) { var projectId = QualifiedModuleName.GetProjectId(vbProject); // use a 'for' loop to store the order of references as a 'priority'. // reference resolver needs this to know which declaration to prioritize when a global identifier exists in multiple libraries. for (var priority = 1; priority <= vbProject.References.Count; priority++) { var reference = vbProject.References.Item(priority); var referencedProjectId = GetReferenceProjectId(reference, projects); ReferencePriorityMap map = null; foreach (var item in _projectReferences) { if (item.ReferencedProjectId == referencedProjectId) { map = map != null ? null : item; } } if (map == null) { map = new ReferencePriorityMap(referencedProjectId) { { projectId, priority } }; _projectReferences.Add(map); } else { map[projectId] = priority; } if (!map.IsLoaded) { State.OnStatusMessageUpdate(ParserState.LoadingReference.ToString()); var tightlyScopedCapture = reference; loadTasks.Add( Task.Run(() => { var comReflector = new ReferencedDeclarationsCollector(State); var items = comReflector.GetDeclarationsForReference(tightlyScopedCapture); foreach (var declaration in items) { State.AddDeclaration(declaration); } })); map.IsLoaded = true; } } } var mappedIds = new List <string>(); foreach (var item in _projectReferences) { mappedIds.Add(item.ReferencedProjectId); } var unmapped = new List <Reference>(); foreach (var project in projects) { foreach (Reference item in project.References) { if (!mappedIds.Contains(GetReferenceProjectId(item, projects))) { unmapped.Add(item); } } } Task.WaitAll(loadTasks.ToArray()); foreach (var reference in unmapped) { UnloadComReference(reference, projects); } }