Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
        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);
            }
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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);
            }
        }