private void Tracker_UpdatedOnDisk(object sender, EventArgs e) { FileChangeTracker tracker = (FileChangeTracker)sender; var filePath = tracker.FilePath; lock (_guard) { // Once we've created a diagnostic for a given analyzer file, there's // no need to keep watching it. _fileChangeTrackers.Remove(filePath); } tracker.Dispose(); tracker.UpdatedOnDisk -= Tracker_UpdatedOnDisk; // Traverse the chain of requesting assemblies to get back to the original analyzer // assembly. var assemblyPath = filePath; var requestingAssemblyPath = InMemoryAssemblyProvider.TryGetRequestingAssembly(filePath); while (requestingAssemblyPath != null) { assemblyPath = requestingAssemblyPath; requestingAssemblyPath = InMemoryAssemblyProvider.TryGetRequestingAssembly(assemblyPath); } var projectsWithAnalyzer = _workspace.ProjectTracker.Projects.Where(p => p.CurrentProjectAnalyzersContains(assemblyPath)).ToArray(); foreach (var project in projectsWithAnalyzer) { RaiseAnalyzerChangedWarning(project.Id, filePath); } }
public void AssemblyLoading() { StringBuilder sb = new StringBuilder(); var directory = Temp.CreateDirectory(); EventHandler <InMemoryAssemblyProvider.AssemblyLoadEventArgs> handler = (e, args) => { var relativePath = args.Path.Substring(directory.Path.Length); sb.AppendFormat("Assembly {0} loaded from {1}", args.LoadedAssembly.FullName, relativePath); sb.AppendLine(); }; InMemoryAssemblyProvider.AssemblyLoad += handler; var alphaDll = directory.CreateFile("Alpha.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Alpha); var betaDll = directory.CreateFile("Beta.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Beta); var gammaDll = directory.CreateFile("Gamma.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Gamma); var deltaDll = directory.CreateFile("Delta.dll").WriteAllBytes(TestResources.AssemblyLoadTests.AssemblyLoadTests.Delta); AnalyzerFileReference alphaReference = CreateAnalyzerFileReference(alphaDll.Path); Assembly alpha = alphaReference.GetAssembly(); File.Delete(alphaDll.Path); var a = alpha.CreateInstance("Alpha.A"); a.GetType().GetMethod("Write").Invoke(a, new object[] { sb, "Test A" }); File.Delete(gammaDll.Path); File.Delete(deltaDll.Path); AnalyzerFileReference betaReference = CreateAnalyzerFileReference(betaDll.Path); Assembly beta = betaReference.GetAssembly(); var b = beta.CreateInstance("Beta.B"); b.GetType().GetMethod("Write").Invoke(b, new object[] { sb, "Test B" }); var expected = @"Assembly Alpha, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Alpha.dll Assembly Gamma, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Gamma.dll Assembly Delta, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Delta.dll Delta: Gamma: Alpha: Test A Assembly Beta, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null loaded from \Beta.dll Delta: Gamma: Beta: Test B "; var actual = sb.ToString(); Assert.Equal(expected, actual); var alphaDllRequestor = InMemoryAssemblyProvider.TryGetRequestingAssembly(alphaDll.Path); var betaDllRequestor = InMemoryAssemblyProvider.TryGetRequestingAssembly(betaDll.Path); var gammaDllRequestor = InMemoryAssemblyProvider.TryGetRequestingAssembly(gammaDll.Path); var deltaDllRequestor = InMemoryAssemblyProvider.TryGetRequestingAssembly(deltaDll.Path); Assert.Null(alphaDllRequestor); Assert.Null(betaDllRequestor); Assert.Equal(expected: alphaDll.Path, actual: gammaDllRequestor, comparer: StringComparer.OrdinalIgnoreCase); Assert.Equal(expected: gammaDll.Path, actual: deltaDllRequestor, comparer: StringComparer.OrdinalIgnoreCase); InMemoryAssemblyProvider.AssemblyLoad -= handler; }