Skip to content

Commit

Permalink
Improve parsing of TargetFramework attribute in UniversalAssemblyReso…
Browse files Browse the repository at this point in the history
…lver.
  • Loading branch information
siegfriedpammer committed Jul 28, 2018
1 parent 1d937bc commit 3d68da7
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 18 deletions.
8 changes: 3 additions & 5 deletions ICSharpCode.Decompiler/Metadata/DotNetCorePathFinder.cs
Expand Up @@ -57,15 +57,13 @@ public DotNetCorePackageInfo(string fullName, string type, string path, string[]
ISet<string> packageBasePaths = new HashSet<string>(StringComparer.Ordinal);
readonly string assemblyName;
readonly string basePath;
readonly string targetFrameworkId;
readonly string version;
readonly Version version;
readonly string dotnetBasePath = FindDotNetExeDirectory();

public DotNetCorePathFinder(string parentAssemblyFileName, string targetFrameworkId, string version, ReferenceLoadInfo loadInfo = null)
public DotNetCorePathFinder(string parentAssemblyFileName, string targetFrameworkId, Version version, ReferenceLoadInfo loadInfo = null)
{
this.assemblyName = Path.GetFileNameWithoutExtension(parentAssemblyFileName);
this.basePath = Path.GetDirectoryName(parentAssemblyFileName);
this.targetFrameworkId = targetFrameworkId;
this.version = version;

var depsJsonFileName = Path.Combine(basePath, $"{assemblyName}.deps.json");
Expand Down Expand Up @@ -98,7 +96,7 @@ public string TryResolveDotNetCore(IAssemblyReference name)
}
}

return FallbackToDotNetSharedDirectory(name, new Version(version));
return FallbackToDotNetSharedDirectory(name, version);
}

static IEnumerable<DotNetCorePackageInfo> LoadPackageInfos(string depsJsonFileName, string targetFramework)
Expand Down
79 changes: 67 additions & 12 deletions ICSharpCode.Decompiler/Metadata/UniversalAssemblyResolver.cs
Expand Up @@ -67,13 +67,24 @@ public string[] GetSearchDirectories()
return directories.ToArray();
}

public string TargetFramework { get; }
enum TargetFrameworkIdentifier
{
NETFramework,
NETCoreApp,
NETStandard,
Silverlight
}

string targetFramework;
TargetFrameworkIdentifier targetFrameworkIdentifier;
Version targetFrameworkVersion;

public UniversalAssemblyResolver(string mainAssemblyFileName, bool throwOnError, string targetFramework,
PEStreamOptions options = PEStreamOptions.Default)
{
this.options = options;
this.TargetFramework = targetFramework ?? string.Empty;
this.targetFramework = targetFramework ?? string.Empty;
(targetFrameworkIdentifier, targetFrameworkVersion) = ParseTargetFramework(this.targetFramework);
this.mainAssemblyFileName = mainAssemblyFileName;
this.baseDirectory = Path.GetDirectoryName(mainAssemblyFileName);
this.throwOnError = throwOnError;
Expand All @@ -82,6 +93,52 @@ public string[] GetSearchDirectories()
AddSearchDirectory(baseDirectory);
}

(TargetFrameworkIdentifier, Version) ParseTargetFramework(string targetFramework)
{
string[] tokens = targetFramework.Split(',');
TargetFrameworkIdentifier identifier;

switch (tokens[0].Trim().ToUpperInvariant()) {
case ".NETCOREAPP":
identifier = TargetFrameworkIdentifier.NETCoreApp;
break;
case ".NETSTANDARD":
identifier = TargetFrameworkIdentifier.NETStandard;
break;
case "SILVERLIGHT":
identifier = TargetFrameworkIdentifier.Silverlight;
break;
default:
identifier = TargetFrameworkIdentifier.NETFramework;
break;
}

Version version = null;

for (int i = 1; i < tokens.Length; i++) {
var pair = tokens[i].Trim().Split('=');

if (pair.Length != 2)
continue;

switch (pair[0].Trim().ToUpperInvariant()) {
case "VERSION":
var versionString = pair[1].TrimStart('v');
if (identifier == TargetFrameworkIdentifier.NETCoreApp ||
identifier == TargetFrameworkIdentifier.NETStandard)
{
if (versionString.Length == 3)
versionString += ".0";
}
if (!Version.TryParse(versionString, out version))
version = null;
break;
}
}

return (identifier, version ?? ZeroVersion);
}

public PEFile Resolve(IAssemblyReference name)
{
var file = FindAssemblyFile(name);
Expand All @@ -107,25 +164,23 @@ public PEFile ResolveModule(PEFile mainModule, string moduleName)

public string FindAssemblyFile(IAssemblyReference name)
{
var targetFramework = TargetFramework.Split(new[] { ",Version=v", ",Profile=" }, StringSplitOptions.None);
string file = null;
switch (targetFramework[0]) {
case ".NETCoreApp":
case ".NETStandard":
if (targetFramework.Length < 2)
switch (targetFrameworkIdentifier) {
case TargetFrameworkIdentifier.NETCoreApp:
case TargetFrameworkIdentifier.NETStandard:
if (IsZeroOrAllOnes(targetFrameworkVersion))
goto default;
if (dotNetCorePathFinder == null) {
var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1];
dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, TargetFramework, version);
dotNetCorePathFinder = new DotNetCorePathFinder(mainAssemblyFileName, targetFramework, targetFrameworkVersion);
}
file = dotNetCorePathFinder.TryResolveDotNetCore(name);
if (file != null)
return file;
goto default;
case "Silverlight":
if (targetFramework.Length < 2)
case TargetFrameworkIdentifier.Silverlight:
if (IsZeroOrAllOnes(targetFrameworkVersion))
goto default;
file = ResolveSilverlight(name, new Version(targetFramework[1]));
file = ResolveSilverlight(name, targetFrameworkVersion);
if (file != null)
return file;
goto default;
Expand Down
2 changes: 1 addition & 1 deletion ILSpy.AddIn/AssemblyFileFinder.cs
Expand Up @@ -30,7 +30,7 @@ public static string FindAssemblyFile(AssemblyDefinition assemblyDefinition, str
case ".NETStandard":
if (targetFramework.Length != 2)
return FindAssemblyFromGAC(assemblyDefinition);
var version = targetFramework[1].Length == 3 ? targetFramework[1] + ".0" : targetFramework[1];
var version = targetFramework[1].Length == 3 ? new Version(targetFramework[1] + ".0") : new Version(targetFramework[1]);
var dotNetCorePathFinder = new DotNetCorePathFinder(assemblyFile, detectedTargetFramework, version);
file = dotNetCorePathFinder.TryResolveDotNetCore(Decompiler.Metadata.AssemblyNameReference.Parse(assemblyName.FullName));
if (file != null)
Expand Down

0 comments on commit 3d68da7

Please sign in to comment.