Skip to content

Commit 2f792f6

Browse files
authored
Improve Framework Id detection (#3581)
* Support detecting .NET Core 1.0 and 1.1 * Formatting * Fix version number * Add support for using System.Private.CoreLib in version detection * Move mscorlib for consistency and readability * Ensure that netstandard is always checked before System.Runtime * Ensure that System.Runtime is always checked before netstandard * Formatting
1 parent 126e870 commit 2f792f6

File tree

1 file changed

+54
-27
lines changed

1 file changed

+54
-27
lines changed

ICSharpCode.Decompiler/Metadata/DotNetCorePathFinderExtensions.cs

Lines changed: 54 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
7979
return $".NETFramework,Version=v{assemblyDefinition.Version.ToString(2)}";
8080
case "netstandard":
8181
return $".NETStandard,Version=v{assemblyDefinition.Version.ToString(2)}";
82+
case "System.Runtime":
83+
case "System.Private.CoreLib":
84+
{
85+
string version = GetDotNetCoreVersion(assemblyDefinition.Version);
86+
if (version != null)
87+
{
88+
return $".NETCoreApp,Version=v{version}";
89+
}
90+
else
91+
{
92+
break;
93+
}
94+
}
8295
}
8396
}
8497

@@ -92,42 +105,20 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
92105
string version;
93106
switch (metadata.GetString(r.Name))
94107
{
95-
case "netstandard":
108+
case "mscorlib":
96109
version = r.Version.ToString(2);
97-
return $".NETStandard,Version=v{version}";
110+
return $".NETFramework,Version=v{version}";
98111
case "System.Runtime":
99-
// System.Runtime.dll uses the following scheme:
100-
// 4.2.0 => .NET Core 2.0
101-
// 4.2.1 => .NET Core 2.1 / 3.0
102-
// 4.2.2 => .NET Core 3.1
103-
// 5.0.0+ => .NET 5+
104-
if (r.Version >= new Version(4, 2, 0))
112+
case "System.Private.CoreLib":
113+
version = GetDotNetCoreVersion(r.Version);
114+
if (version != null)
105115
{
106-
if (r.Version.Major >= 5)
107-
{
108-
version = r.Version.ToString(2);
109-
}
110-
else if (r.Version.Major == 4 && r.Version.Minor == 2)
111-
{
112-
version = r.Version.Build switch {
113-
<= 0 => "2.0",
114-
1 => "3.0",
115-
_ => "3.1"
116-
};
117-
}
118-
else
119-
{
120-
version = "2.0";
121-
}
122116
return $".NETCoreApp,Version=v{version}";
123117
}
124118
else
125119
{
126120
continue;
127121
}
128-
case "mscorlib":
129-
version = r.Version.ToString(2);
130-
return $".NETFramework,Version=v{version}";
131122
}
132123
}
133124
catch (BadImageFormatException)
@@ -136,6 +127,24 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
136127
}
137128
}
138129

130+
// We check for netstandard separately because .NET Core/Framework assemblies can reference it.
131+
foreach (var h in metadata.AssemblyReferences)
132+
{
133+
try
134+
{
135+
var r = metadata.GetAssemblyReference(h);
136+
if (r.PublicKeyOrToken.IsNil || metadata.GetString(r.Name) is not "netstandard")
137+
continue;
138+
139+
string version = r.Version.ToString(2);
140+
return $".NETStandard,Version=v{version}";
141+
}
142+
catch (BadImageFormatException)
143+
{
144+
// ignore malformed references
145+
}
146+
}
147+
139148
// Optionally try to detect target version through assembly path as a fallback (use case: reference assemblies)
140149
if (assemblyPath != null)
141150
{
@@ -185,6 +194,24 @@ public static string DetectTargetFrameworkId(this MetadataReader metadata, strin
185194
return string.Empty;
186195
}
187196

197+
static string GetDotNetCoreVersion(Version assemblyVersion)
198+
{
199+
// System.Runtime.dll and System.Private.CoreLib.dll use the following scheme:
200+
// 4.1.0 => .NET Core 1.0 / 1.1
201+
// 4.2.0 => .NET Core 2.0
202+
// 4.2.1 => .NET Core 2.1 / 3.0
203+
// 4.2.2 => .NET Core 3.1
204+
// 5.0.0+ => .NET 5+
205+
return (assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Build) switch {
206+
(4, 1, 0) => "1.1",
207+
(4, 2, 0) => "2.0",
208+
(4, 2, 1) => "3.0",
209+
(4, 2, 2) => "3.1",
210+
( >= 5, _, _) => assemblyVersion.ToString(2),
211+
_ => null
212+
};
213+
}
214+
188215
public static bool IsReferenceAssembly(this MetadataFile assembly)
189216
{
190217
return IsReferenceAssembly(assembly.Metadata, assembly.FileName);

0 commit comments

Comments
 (0)