Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit d73815f

Browse files
[XamlC] accomodate all kinds of netstandard versions
1 parent d31d28b commit d73815f

File tree

4 files changed

+55
-14
lines changed

4 files changed

+55
-14
lines changed

Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2828
classArguments: new[] { ("mscorlib", "System", "String") });
2929

3030
yield return Instruction.Create(OpCodes.Ldc_I4, parts.Count);
31-
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("mscorlib", "System.Collections.Generic", "List`1"),
31+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("System.Collections", "System.Collections.Generic", "List`1"),
3232
paramCount: 1,
3333
predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int32",
3434
classArguments: new[] { ("mscorlib", "System", "String") }));

Xamarin.Forms.Build.Tasks/ModuleDefinitionExtensions.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,34 @@ public static MethodReference ImportMethodReference(this ModuleDefinition module
139139
classArguments?.Select(gp => module.GetTypeDefinition((gp.assemblyName, gp.clrNamespace, gp.typeName))).ToArray());
140140
}
141141

142+
static Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition> typeDefCache
143+
= new Dictionary<(ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName)), TypeDefinition>();
144+
142145
public static TypeDefinition GetTypeDefinition(this ModuleDefinition module, (string assemblyName, string clrNamespace, string typeName) type)
143146
{
147+
if (typeDefCache.TryGetValue((module, type), out TypeDefinition cachedTypeDefinition))
148+
return cachedTypeDefinition;
149+
144150
var asm = module.Assembly.Name.Name == type.assemblyName
145151
? module.Assembly
146152
: module.AssemblyResolver.Resolve(AssemblyNameReference.Parse(type.assemblyName));
147153
var typeDef = asm.MainModule.GetType($"{type.clrNamespace}.{type.typeName}");
148-
if (typeDef != null)
154+
if (typeDef != null) {
155+
typeDefCache.Add((module, type), typeDef);
149156
return typeDef;
157+
}
150158
var exportedType = asm.MainModule.ExportedTypes.FirstOrDefault(
151-
(ExportedType arg) => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName);
152-
if (exportedType != null)
153-
return exportedType.Resolve();
154-
return null;
159+
arg => arg.IsForwarder && arg.Namespace == type.clrNamespace && arg.Name == type.typeName);
160+
if (exportedType != null) {
161+
typeDef = exportedType.Resolve();
162+
typeDefCache.Add((module, type), typeDef);
163+
return typeDef;
164+
}
165+
166+
//I hate you, netstandard
167+
if (type.assemblyName == "mscorlib" && type.clrNamespace == "System.Reflection")
168+
return module.GetTypeDefinition(("System.Reflection", type.clrNamespace, type.typeName));
169+
throw new Exception($"Failed to get typedef for {type}");
155170
}
156171

157172
static IEnumerable<PropertyDefinition> Properties(this TypeDefinition typedef, bool flatten)

Xamarin.Forms.Build.Tasks/NodeILExtensions.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,16 +443,10 @@ static IEnumerable<Instruction> PushTargetProperty(FieldReference bpRef, Propert
443443
yield break;
444444
}
445445
if (propertyRef != null) {
446-
// IL_0000: ldtoken [mscorlib]System.String
447-
// IL_0005: call class [mscorlib]System.Type class [mscorlib] System.Type::GetTypeFromHandle(valuetype [mscorlib] System.RuntimeTypeHandle)
448-
// IL_000a: ldstr "Foo"
449-
// IL_000f: callvirt instance class [mscorlib] System.Reflection.PropertyInfo class [mscorlib] System.Type::GetProperty(string)
450-
var getTypeFromHandle = module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic);
451-
var getPropertyInfo = module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetProperty", paramCount: 1);
452446
yield return Create(Ldtoken, module.ImportReference(declaringTypeReference ?? propertyRef.DeclaringType));
453-
yield return Create(Call, module.ImportReference(getTypeFromHandle));
447+
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic));
454448
yield return Create(Ldstr, propertyRef.Name);
455-
yield return Create(Callvirt, module.ImportReference(getPropertyInfo));
449+
yield return Create(Call, module.ImportMethodReference(("System.Reflection.Extensions", "System.Reflection", "RuntimeReflectionExtensions"), methodName: "GetRuntimeProperty", paramCount: 2));
456450
yield break;
457451
}
458452
yield return Create(Ldnull);

Xamarin.Forms.Build.Tasks/XamlCAssemblyResolver.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using Mono.Cecil;
23

34
namespace Xamarin.Forms.Build.Tasks
@@ -11,5 +12,36 @@ public void AddAssembly(string p)
1112
AssemblyResolver = this
1213
}));
1314
}
15+
16+
public override AssemblyDefinition Resolve(AssemblyNameReference name)
17+
{
18+
if (TryResolve(name, out AssemblyDefinition assembly))
19+
return assembly;
20+
if ( IsMscorlib(name)
21+
&& ( TryResolve(AssemblyNameReference.Parse("mscorlib"), out assembly)
22+
|| TryResolve(AssemblyNameReference.Parse("netstandard"), out assembly)
23+
|| TryResolve(AssemblyNameReference.Parse("System.Runtime"), out assembly)))
24+
return assembly;
25+
throw new AssemblyResolutionException(name);
26+
}
27+
28+
bool TryResolve(AssemblyNameReference assemblyNameReference, out AssemblyDefinition assembly)
29+
{
30+
try {
31+
assembly = base.Resolve(assemblyNameReference);
32+
return true;
33+
}
34+
catch (AssemblyResolutionException) {
35+
assembly = null;
36+
return false;
37+
}
38+
}
39+
40+
static bool IsMscorlib(AssemblyNameReference name)
41+
{
42+
return name.Name == "mscorlib"
43+
|| name.Name == "System.Runtime"
44+
|| name.Name == "netstandard";
45+
}
1446
}
1547
}

0 commit comments

Comments
 (0)