Skip to content

Commit

Permalink
fix: Handle types correctly in ResourceDictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 committed Sep 14, 2021
1 parent daf7611 commit 11b8a40
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
29 changes: 29 additions & 0 deletions src/Uno.UI.Tests/Windows_UI_Xaml/Given_ResourceDictionary.cs
Expand Up @@ -46,6 +46,35 @@ public void When_Simple_Add_And_Retrieve()
Assert.AreEqual(Colors.DarkOliveGreen, ((SolidColorBrush)retrieved2).Color);
}

[TestMethod]
public void When_Simple_Add_And_Retrieve_Type_Key()
{
var rd = new ResourceDictionary();

// NOTE: Intentionally using a type outside of Uno.UI to prevent regressions if someone thought to use Type.GetType.
// See: https://stackoverflow.com/a/1825156/5108631
// Type.GetType(...) only works when the type is found in either mscorlib.dll or the currently executing assembly.
rd[typeof(Given_ResourceDictionary)] = nameof(When_Simple_Add_And_Retrieve_Type_Key);

var retrieved = rd[typeof(Given_ResourceDictionary)];

Assert.IsTrue(rd.ContainsKey(typeof(Given_ResourceDictionary)));
Assert.IsFalse(rd.ContainsKey("Uno.UI.Tests.Windows_UI_Xaml.Given_ResourceDictionary"));

Assert.AreEqual(nameof(When_Simple_Add_And_Retrieve_Type_Key), retrieved);

rd.TryGetValue(typeof(Given_ResourceDictionary), out var retrieved2);
Assert.AreEqual(nameof(When_Simple_Add_And_Retrieve_Type_Key), retrieved2);

var key = rd.Keys.Single();
Assert.AreEqual(typeof(Given_ResourceDictionary), key);

foreach (var kvp in rd)
{
Assert.AreEqual(typeof(Given_ResourceDictionary), kvp.Key);
}
}

[TestMethod]
public void When_Key_Not_Present()
{
Expand Down
8 changes: 4 additions & 4 deletions src/Uno.UI/UI/Xaml/ResourceDictionary.cs
Expand Up @@ -387,10 +387,10 @@ private void CopyFrom(ResourceDictionary source)
}

public global::System.Collections.Generic.ICollection<object> Keys
=> _values.Keys.Select(k => ConvertKey(k.Key)).ToList();
=> _values.Keys.Select(k => ConvertKey(k)).ToList();

private static object ConvertKey(ResourceKey resourceKey)
=> resourceKey.IsType ? Type.GetType(resourceKey.Key) : (object)resourceKey.Key;
=> resourceKey.IsType ? resourceKey.TypeKey : (object)resourceKey.Key;

// TODO: this doesn't handle lazy initializers or aliases
public global::System.Collections.Generic.ICollection<object> Values => _values.Values;
Expand Down Expand Up @@ -442,11 +442,11 @@ public bool IsParsing
var aliased = kvp.Value;
if (TryResolveAlias(ref aliased))
{
yield return new KeyValuePair<object, object>(ConvertKey(kvp.Key.Key), aliased);
yield return new KeyValuePair<object, object>(ConvertKey(kvp.Key), aliased);
}
else
{
yield return new KeyValuePair<object, object>(ConvertKey(kvp.Key.Key), kvp.Value);
yield return new KeyValuePair<object, object>(ConvertKey(kvp.Key), kvp.Value);
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/Uno.UI/UI/Xaml/SpecializedResourceDictionary.cs
Expand Up @@ -31,6 +31,7 @@ internal class SpecializedResourceDictionary
public readonly struct ResourceKey
{
public readonly string Key;
public readonly Type TypeKey;
public readonly bool IsType;
public readonly uint HashCode;

Expand All @@ -41,6 +42,7 @@ internal class SpecializedResourceDictionary
private ResourceKey(bool dummy)
{
Key = null;
TypeKey = null;
IsType = false;
HashCode = 0;
}
Expand All @@ -54,12 +56,14 @@ public ResourceKey(object key)
if (key is string s)
{
Key = s;
TypeKey = null;
IsType = false;
HashCode = (uint)(s.GetHashCode() ^ IsType.GetHashCode());
}
else if (key is Type t)
{
Key = t.ToString();
TypeKey = t;
IsType = true;
HashCode = (uint)(t.GetHashCode() ^ IsType.GetHashCode());
}
Expand All @@ -72,6 +76,7 @@ public ResourceKey(object key)
else
{
Key = key.ToString();
TypeKey = null;
IsType = false;
HashCode = (uint)(key.GetHashCode() ^ IsType.GetHashCode());
}
Expand All @@ -84,6 +89,7 @@ public ResourceKey(object key)
public ResourceKey(string key)
{
Key = key;
TypeKey = null;
IsType = false;
HashCode = (uint)(key.GetHashCode() ^ IsType.GetHashCode());
}
Expand All @@ -95,6 +101,7 @@ public ResourceKey(string key)
public ResourceKey(Type key)
{
Key = key.ToString();
TypeKey = key;
IsType = true;
HashCode = (uint)(key.GetHashCode() ^ IsType.GetHashCode());
}
Expand Down

0 comments on commit 11b8a40

Please sign in to comment.