public override void Merge(IPsiSourceFile sourceFile, object builtPart) { if (builtPart == null) { // Indirect dependency invalidation RemoveFromDirty(sourceFile); // Merge can happen when a current file is an indirect dependency // of a file that was moved between PSI modules. // In that case we need to set set up includers for all the includes var includes = new JetHashSet <IPsiSourceFile>(GetIncludes(sourceFile) ?? EmptyList <IPsiSourceFile> .Instance); if (UpdateIncluders(ReversedMap, sourceFile, includes, JetHashSet <IPsiSourceFile> .Empty)) { // This means that the file was updated because its indirect dependency // was moved from one PSI module to another. // This means that that dependency should now be updated. // We'll update all of them just in case. var invalidationData = new T4FileInvalidationData( includes.Except(sourceFile), sourceFile ); OnFilesIndirectlyAffected.Fire(invalidationData); } return; } var data = (T4IncludeData)builtPart.NotNull(); var oldTransitiveIncludes = FindIndirectIncludesTransitiveClosure(sourceFile); var oldIncludes = new JetHashSet <IPsiSourceFile>( GetIncludes(sourceFile) ?? EmptyList <IPsiSourceFile> .Instance ); base.Merge(sourceFile, new T4FileDependencyData(data.Includes)); var newTransitiveIncludes = FindIndirectIncludesTransitiveClosure(sourceFile); var newIncludes = new JetHashSet <IPsiSourceFile>( GetIncludes(sourceFile) ?? EmptyList <IPsiSourceFile> .Instance ); var fileInvalidationData = new T4FileInvalidationData( oldTransitiveIncludes.Union(newTransitiveIncludes).Except(sourceFile), sourceFile ); OnFilesIndirectlyAffected.Fire(fileInvalidationData); oldIncludes.Compare(newIncludes, out var addedItems, out var removedItems); UpdateIncluders(ReversedMap, sourceFile, addedItems, removedItems); }