Skip to content

Commit

Permalink
Revert "Reduce File I/O under the AnalyzerAssemblyLoader folder (dotn…
Browse files Browse the repository at this point in the history
…et#72412)"

This reverts commit 02069ce.
  • Loading branch information
Cosifne committed Nov 5, 2024
1 parent 26920eb commit 2132105
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 237 deletions.
50 changes: 4 additions & 46 deletions src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using Xunit.Abstractions;
using Xunit.Sdk;
using Microsoft.CodeAnalysis.VisualBasic;

#if NET
Expand Down Expand Up @@ -368,32 +370,11 @@ string getExpectedLoadPath(string path)

if (path.EndsWith(".resources.dll", StringComparison.Ordinal))
{
return getRealSatelliteLoadPath(path) ?? "";
return loader.GetRealSatelliteLoadPath(path) ?? "";
}
return loader.GetRealAnalyzerLoadPath(path ?? "");
}

// When PreparePathToLoad is overridden this returns the most recent
// real path for the given analyzer satellite assembly path
string? getRealSatelliteLoadPath(string originalSatelliteFullPath)
{
// This is a satellite assembly, need to find the mapped path of the real assembly, then
// adjust that mapped path for the suffix of the satellite assembly
//
// Example of dll and it's corresponding satellite assembly
//
// c:\some\path\en-GB\util.resources.dll
// c:\some\path\util.dll
var assemblyFileName = Path.ChangeExtension(Path.GetFileNameWithoutExtension(originalSatelliteFullPath), ".dll");

var assemblyDir = Path.GetDirectoryName(originalSatelliteFullPath)!;
var cultureInfo = CultureInfo.GetCultureInfo(Path.GetFileName(assemblyDir));
assemblyDir = Path.GetDirectoryName(assemblyDir)!;

// Real assembly is located in the directory above this one
var assemblyPath = Path.Combine(assemblyDir, assemblyFileName);
return loader.GetRealSatelliteLoadPath(assemblyPath, cultureInfo);
}
}

private static void VerifyAssemblies(AnalyzerAssemblyLoader loader, IEnumerable<Assembly> assemblies, int? copyCount, params string[] assemblyPaths)
Expand Down Expand Up @@ -1443,31 +1424,8 @@ public void AssemblyLoading_Resources(AnalyzerTestKind kind)
// dlls don't apply for this count.
VerifyDependencyAssemblies(loader, copyCount: 1, analyzerPath, analyzerResourcesPath);
});
}

[Theory]
[CombinatorialData]
public void AssemblyLoading_ResourcesInParent(AnalyzerTestKind kind)
{
Run(kind, static (AnalyzerAssemblyLoader loader, AssemblyLoadTestFixture testFixture) =>
{
using var temp = new TempRoot();
var tempDir = temp.CreateDirectory();
var analyzerPath = tempDir.CreateFile("AnalyzerWithLoc.dll").CopyContentFrom(testFixture.AnalyzerWithLoc).Path;
var analyzerResourcesPath = tempDir.CreateDirectory("es").CreateFile("AnalyzerWithLoc.resources.dll").CopyContentFrom(testFixture.AnalyzerWithLocResourceEnGB).Path;
loader.AddDependencyLocation(analyzerPath);
var assembly = loader.LoadFromPath(analyzerPath);
var methodInfo = assembly
.GetType("AnalyzerWithLoc.Util")!
.GetMethod("Exec", BindingFlags.Static | BindingFlags.Public)!;
methodInfo.Invoke(null, ["es-ES"]);

// The copy count is 1 here as only one real assembly was copied, the resource
// dlls don't apply for this count.
VerifyDependencyAssemblies(loader, copyCount: 1, analyzerPath, analyzerResourcesPath);
});
}

#if NET

[Theory]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader)
var assemblyPath = Path.Combine(Directory, simpleName + ".dll");
if (_loader.IsAnalyzerDependencyPath(assemblyPath))
{
(_, var loadPath) = _loader.GetAssemblyInfoForPath(assemblyPath);
(_, var loadPath, _) = _loader.GetAssemblyInfoForPath(assemblyPath);
return loadCore(loadPath);
}

Expand All @@ -156,11 +156,11 @@ public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader)
// loader has a mode where it loads from Stream though and the runtime will not handle
// that automatically. Rather than bifurcate our loading behavior between Disk and
// Stream both modes just handle satellite loading directly
if (assemblyName.CultureInfo is not null && simpleName.EndsWith(".resources", StringComparison.Ordinal))
if (!string.IsNullOrEmpty(assemblyName.CultureName) && simpleName.EndsWith(".resources", StringComparison.Ordinal))
{
var analyzerFileName = Path.ChangeExtension(simpleName, ".dll");
var analyzerFilePath = Path.Combine(Directory, analyzerFileName);
var satelliteLoadPath = _loader.GetRealSatelliteLoadPath(analyzerFilePath, assemblyName.CultureInfo);
var satelliteLoadPath = _loader.GetSatelliteInfoForPath(analyzerFilePath, assemblyName.CultureName);
if (satelliteLoadPath is not null)
{
return loadCore(satelliteLoadPath);
Expand All @@ -173,8 +173,7 @@ public DirectoryLoadContext(string directory, AnalyzerAssemblyLoader loader)
// be necessary but msbuild target defaults have caused a number of customers to
// fall into this path. See discussion here for where it comes up
// https://github.com/dotnet/roslyn/issues/56442
var (_, bestRealPath) = _loader.GetBestPath(assemblyName);
if (bestRealPath is not null)
if (_loader.GetBestPath(assemblyName) is string bestRealPath)
{
return loadCore(bestRealPath);
}
Expand All @@ -201,7 +200,7 @@ protected override IntPtr LoadUnmanagedDll(string unmanagedDllName)
var assemblyPath = Path.Combine(Directory, unmanagedDllName + ".dll");
if (_loader.IsAnalyzerDependencyPath(assemblyPath))
{
(_, var loadPath) = _loader.GetAssemblyInfoForPath(assemblyPath);
(_, var loadPath, _) = _loader.GetAssemblyInfoForPath(assemblyPath);
return LoadUnmanagedDllFromPath(loadPath);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,30 +117,11 @@ internal bool EnsureResolvedUnhooked()
{
try
{
const string resourcesExtension = ".resources";
var assemblyName = new AssemblyName(args.Name);
var simpleName = assemblyName.Name;
var isSatelliteAssembly =
assemblyName.CultureInfo is not null &&
simpleName.EndsWith(resourcesExtension, StringComparison.Ordinal);

if (isSatelliteAssembly)
{
// Satellite assemblies should get the best path information using the
// non-resource part of the assembly name. Once the path information is obtained
// GetSatelliteInfoForPath will translate to the resource assembly path.
assemblyName.Name = simpleName[..^resourcesExtension.Length];
}

var (originalPath, realPath) = GetBestPath(assemblyName);
if (isSatelliteAssembly && originalPath is not null)
{
realPath = GetRealSatelliteLoadPath(originalPath, assemblyName.CultureInfo);
}

if (realPath is not null)
string? bestPath = GetBestPath(assemblyName);
if (bestPath is not null)
{
return Assembly.LoadFrom(realPath);
return Assembly.LoadFrom(bestPath);
}

return null;
Expand Down
Loading

0 comments on commit 2132105

Please sign in to comment.