Пример #1
0
        public override object Load([NotNull] IProgressIndicator progress, bool enablePersistence)
        {
            base.Load(progress, enablePersistence);
            // Map is loaded on class instantiation
            progress.CurrentItemText = "Loading T4 file include caches";
            var result    = new Dictionary <IPsiSourceFile, T4ReversedFileDependencyData>();
            var stopWatch = new Stopwatch();

            stopWatch.Start();
            foreach (var(sourceFile, data) in Map)
            {
                // This lock is intentionally taken per-file to avoid too long blocking. Just in case.
                using (ReadLockCookie.Create())
                {
                    var includes = new JetHashSet <IPsiSourceFile>(
                        data.Includes.Select(include => PsiFileSelector.FindMostSuitableFile(include, sourceFile))
                        );
                    UpdateIncluders(result, sourceFile, includes, JetHashSet <IPsiSourceFile> .Empty);
                }
            }

            stopWatch.Stop();
            Logger.Verbose("Loading T4 cache took {0} ms", stopWatch.ElapsedMilliseconds);
            return(result);
        }
Пример #2
0
        public override void Drop(IPsiSourceFile sourceFile)
        {
            // Calculate them here, because following actions
            // will disturb the graph and change the dependencies
            var includePaths         = Map.TryGetValue(sourceFile);
            var indirectDependencies = FindIndirectIncludesTransitiveClosure(sourceFile);

            // First of all, this file itself should be removed from Map and ReversedMap
            base.Drop(sourceFile);
            ReversedMap.Remove(sourceFile);

            // Then, all its includes should no longer view this file as an includer.
            // This deletion might be a genuine deletion of the file from the file system,
            // and nonexistent files obviously don't include anything.
            // If this drop was caused by moving the file between PSI modules,
            // it will be re-added into lists of includers by the Merge method.
            var location = sourceFile.GetLocation();
            var includes = includePaths?.Includes
                           .Select(includePath => PsiFileSelector.FindMostSuitableFile(includePath, sourceFile))
                           .WhereNotNull() ?? EmptyList <IPsiSourceFile> .InstanceList;

            foreach (var include in includes)
            {
                ReversedMap.TryGetValue(include)?.Includers.Remove(location);
            }

            // Finally, we trigger indirect include invalidation.
            // Deletion can happen either when the file is genuinely deleted,
            // or when it is transferred between PSI modules
            // (e.g. a file that used to be preprocessed becomes executable).
            // In either case, we need to update its indirect dependencies.
            // However, that cannot be done in Merge,
            // because Merge happens on the new PSI file.
            // That's why we update dependencies here.
            var data = new T4FileInvalidationData(indirectDependencies.Except(sourceFile), sourceFile);

            OnFilesIndirectlyAffected.Fire(data);
        }
Пример #3
0
 private IEnumerable <IPsiSourceFile> GetIncludes([NotNull] IPsiSourceFile sourceFile) => Map
 .TryGetValue(sourceFile)
 ?.Includes
 .Select(path => PsiFileSelector.FindMostSuitableFile(path, sourceFile));