in resharper/resharper-unity/src/Unity/Core/Psi/Modules/UnityExternalFilesModuleProcessor.cs [387:445]
private void SubscribeToProjectModelUpdates()
{
// If any of our external files are added to a proper project, remove them from our external files module.
// Add them back if they're removed from the project model. This can happen if the user generates projects
// for registry packages, or changes the settings to add .unity or .prefab to projects, or manually edits
// the project to add the files (although this will get overwritten)
myChangeManager.Changed.Advise(myLifetime, args =>
{
var solutionChanges = args.ChangeMap.GetChanges<SolutionChange>().ToList();
if (solutionChanges.IsEmpty())
return;
var processedFiles = new HashSet<VirtualFileSystemPath>(); // avoid DEXP-730021 SourceFile is not valid.
var builder = new PsiModuleChangeBuilder();
var visitor = new RecursiveProjectModelChangeDeltaVisitor(null, itemChange =>
{
// Only handle changes to files in "real" projects - this means we need to remove our external file,
// as it's no longer external to the project. Don't process Misc Files project files - these are
// handled automatically by VS, or in response to adding/removing an external PSI file in Rider
// (which would lead to an infinite loop).
// Note that GetOldProject returns the project the file is being added to, or the project it has
// just been removed from
// Warning: Removing .Player project should not cause adding file to the ExternalModule
if (itemChange.ProjectItem is IProjectFile projectFile
&& IsIndexedExternalFile(projectFile.Location))
{
if ((itemChange.IsAdded || itemChange.IsMovedIn) && !itemChange.ProjectItem.IsMiscProjectItem())
{
myLogger.Trace(
"External Unity file added to project {0}. Removing from external files module: {1}",
projectFile.GetProject()?.Name ?? "<null>", projectFile.Location);
RemoveExternalPsiSourceFile(builder, projectFile.Location);
}
else if ((itemChange.IsRemoved || itemChange.IsMovedOut) && itemChange.OldLocation.ExistsFile
&& mySolution.FindProjectItemsByLocation(itemChange.OldLocation).All(t => t.IsMiscProjectItem()))
{
var isUserEditable = IsUserEditable(itemChange.OldLocation, out var isKnownExternalFile);
if (isKnownExternalFile && !processedFiles.Contains(itemChange.OldLocation))
{
myLogger.Trace(
"External Unity file removed from project {0}. Adding to external files module: {1}",
itemChange.GetOldProject()?.Name ?? "<null>", itemChange.OldLocation);
processedFiles.Add(itemChange.OldLocation);
AddOrUpdateExternalPsiSourceFile(builder, itemChange.OldLocation,
myProjectFileExtensions.GetFileType(projectFile.Location), isUserEditable);
}
}
}
});
foreach (var solutionChange in solutionChanges)
solutionChange.Accept(visitor);
if (!builder.IsEmpty)
myChangeManager.ExecuteAfterChange(() => FlushChanges(builder));
});
}