Skip to content

Commit

Permalink
Fixed compilation error on x:Name on non-dependecy objects
Browse files Browse the repository at this point in the history
Bug #846
  • Loading branch information
carldebilly committed Jun 20, 2019
1 parent ce00ff4 commit 7ae1eb9
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 25 deletions.
8 changes: 8 additions & 0 deletions src/SamplesApp/UITests.Shared/UITests.Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\Resources\XamlLocalResources.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\TouchEventsTests\TappedEventTest.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
Expand Down Expand Up @@ -2107,6 +2111,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\Localization\Localization_Implicit.xaml.cs">
<DependentUpon>Localization_Implicit.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\Resources\XamlLocalResources.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\TouchEventsTests\ControlWithTouchEvent.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\TouchEventsTests\TappedEventTest.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Windows_UI_Xaml\TouchEventsTests\Touch.xaml.cs" />
Expand Down Expand Up @@ -3705,6 +3710,9 @@
<Compile Update="C:\src\Uno\src\SamplesApp\UITests.Shared\Windows_UI_Xaml\Resources\XamlGlobalResources.xaml.cs">
<DependentUpon>XamlGlobalResources.xaml</DependentUpon>
</Compile>
<Compile Update="C:\src\Uno\src\SamplesApp\UITests.Shared\Windows_UI_Xaml\Resources\XamlLocalResources.xaml.cs">
<DependentUpon>XamlLocalResources.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)Assets\cart.png" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Page
x:Class="UITests.Shared.Windows_UI_Xaml.Resources.XamlLocalResources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UITests.Shared.Windows_UI_Xaml.Resources"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Page.Resources>
<local:CustomTemplateSelector x:Name="resourceWithAName" />
<SolidColorBrush x:Name="Blue2">Blue</SolidColorBrush>
<Style TargetType="TextBlock" x:Name="myStyle">
</Style>
</Page.Resources>

<!-- This is not a real sample, it's just to ensure the previous resources are not generating any compilation errors -->
</Page>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Windows.UI.Xaml.Controls;
using Uno.UI.Samples.Controls;

namespace UITests.Shared.Windows_UI_Xaml.Resources
{
public sealed partial class XamlLocalResources : Page
{
public XamlLocalResources()
{
this.InitializeComponent();
}
}

internal class CustomTemplateSelector : DataTemplateSelector
{

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Uno.UI.SourceGenerators.XamlGenerator.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -73,13 +74,15 @@ internal partial class XamlFileGenerator
private readonly INamedTypeSymbol _stringSymbol;
private readonly INamedTypeSymbol _objectSymbol;
private readonly INamedTypeSymbol _iFrameworkElementSymbol;
private readonly INamedTypeSymbol _dependencyObjectSymbol;

private readonly INamedTypeSymbol _iCollectionSymbol;
private readonly INamedTypeSymbol _iCollectionOfTSymbol;
private readonly INamedTypeSymbol _iListSymbol;
private readonly INamedTypeSymbol _iListOfTSymbol;
private readonly INamedTypeSymbol _iDictionaryOfTKeySymbol;
private readonly INamedTypeSymbol _dataBindingSymbol;
private readonly INamedTypeSymbol _styleSymbol;

private readonly bool _isWasm;

Expand Down Expand Up @@ -130,12 +133,14 @@ bool isDebug
_elementStubSymbol = GetType(XamlConstants.Types.ElementStub);
_contentPresenterSymbol = GetType(XamlConstants.Types.ContentPresenter);
_iFrameworkElementSymbol = GetType(XamlConstants.Types.IFrameworkElement);
_dependencyObjectSymbol = GetType(XamlConstants.Types.DependencyObject);
_iCollectionSymbol = GetType("System.Collections.ICollection");
_iCollectionOfTSymbol = GetType("System.Collections.Generic.ICollection`1");
_iListSymbol = GetType("System.Collections.IList");
_iListOfTSymbol = GetType("System.Collections.Generic.IList`1");
_iDictionaryOfTKeySymbol = GetType("System.Collections.Generic.IDictionary`2");
_dataBindingSymbol = GetType("Windows.UI.Xaml.Data.Binding");
_styleSymbol = GetType(XamlConstants.Types.Style);

_isWasm = isWasm;
}
Expand Down Expand Up @@ -855,20 +860,39 @@ IEnumerable<KeyValuePair<string, XamlObjectDefinition>> namedResources
writer.AppendLineInvariant(0, ";", namedResource.Value.Type);
}

// Styles are handled differently for now, and there's no variable generated
// for those entries. Skip the ApplyCompiledBindings for those. See
// ImportResourceDictionary handling of x:Name for more details.
var namedResourcesExcludingStyles = namedResources
.Where(nr => nr.Value.Type.Name.Equals("Style", StringComparison.Ordinal))
bool IsGenerateCompiledBindings(KeyValuePair<string, XamlObjectDefinition> nr)
{
var type = GetType(nr.Value.Type);

// Styles are handled differently for now, and there's no variable generated
// for those entries. Skip the ApplyCompiledBindings for those. See
// ImportResourceDictionary handling of x:Name for more details.
if (type.Equals(_styleSymbol))
{
return false;
}

if (type.AllInterfaces.Any(i => i.Equals(_dependencyObjectSymbol)))
{
return true;
}

return false;
}

var resourcesTogenerateApplyCompiledBindings = namedResources
.Where(IsGenerateCompiledBindings)
.ToArray();

if (namedResourcesExcludingStyles.Any())
if (resourcesTogenerateApplyCompiledBindings.Any())
{
using (writer.BlockInvariant("Loading += (s, e) =>"))
{
foreach (var namedResource in namedResourcesExcludingStyles)
foreach (var namedResource in resourcesTogenerateApplyCompiledBindings)
{
writer.AppendFormatInvariant($"{namedResource.Key}.ApplyCompiledBindings();");
var type = GetType(namedResource.Value.Type);

writer.AppendLineInvariant($"{namedResource.Key}.ApplyCompiledBindings();");
}
}
writer.AppendLineInvariant(0, ";");
Expand Down Expand Up @@ -962,7 +986,7 @@ IEnumerable<KeyValuePair<string, XamlObjectDefinition>> keyedResources
}
else
{
// If there is no method suffix,
// If there is no method suffix,
using (writer.BlockInvariant("public static object FindResource(string name)"))
{
BuildGetResources(writer, keyedResources);
Expand Down Expand Up @@ -1678,7 +1702,7 @@ private void RegisterResources(XamlObjectDefinition topLevelControl)

if (isExplicitResDictionary)
{
// To be able to have MergedDictionaries, the first node of the Resource node
// To be able to have MergedDictionaries, the first node of the Resource node
// must be an explicit resource dictionary.

resourcesMember = FindImplicitContentMember(resourcesMember.Objects.First());
Expand Down Expand Up @@ -1731,8 +1755,8 @@ private void TryExtractAutomationId(XamlMemberDefinition member, string[] target

var fullMemberName = $"{FindType(member.Member.DeclaringType)?.GetFullMetadataName()}.{member.Member.Name}";

// Try to match each potential candidate by comparing based only on the name of the member first.
// If that fails, try matching based on the full metadata name of the member
// Try to match each potential candidate by comparing based only on the name of the member first.
// If that fails, try matching based on the full metadata name of the member
var hasUiAutomationMapping = targetMembers
.Any(candidateMember =>
(!candidateMember.Contains(".") && candidateMember == member.Member.Name) ||
Expand All @@ -1752,7 +1776,7 @@ private void TryExtractAutomationId(XamlMemberDefinition member, string[] target

string bindingPath;

// Checks the first binding member, which can be used to implicitlty declare the binding path (i.e. without
// Checks the first binding member, which can be used to implicitlty declare the binding path (i.e. without
// declaring a "Path=" specifier). Otherwise, the we look for any explicit binding path declaration.
var firstBindingMember = bindingMembers?.FirstOrDefault();
if (firstBindingMember != null &&
Expand Down Expand Up @@ -2162,7 +2186,7 @@ private void TryValidateContentPresenterBinding(IIndentedStringBuilder writer, X
var hasRelativeSource = binding.Members
.Any(m =>
m.Member.Name == "RelativeSource"
// It can either be TemplatedParent or Self. In either cases, it does not use the inherited
// It can either be TemplatedParent or Self. In either cases, it does not use the inherited
// DataContext, which falls outside of the scenario we want to avoid.
);

Expand Down Expand Up @@ -2229,9 +2253,9 @@ private XamlLazyApplyBlockIIndentedStringBuilder CreateApplyBlock(IIndentedStrin
closureName = "c" + (_applyIndex++).ToString(CultureInfo.InvariantCulture);

//
// Since we're using strings to generate the code, we can't know ahead of time if
// Since we're using strings to generate the code, we can't know ahead of time if
// content will be generated only by looking at the Xaml object model.
// For now, we only observe if the inner code has generated code, and we create
// For now, we only observe if the inner code has generated code, and we create
// the apply block at that time.
//
string delegateType = null;
Expand Down Expand Up @@ -2604,7 +2628,7 @@ private string BuildLiteralValue(INamedTypeSymbol propertyType, string memberVal

throw new Exception("Unable to convert {0} for {1} with type {2}".InvariantCultureFormat(memberValue, memberName, propertyType));
}

private string BuildLocalizedResourceValue(XamlMemberDefinition owner, string memberName, string objectUid)
{
var uidParts = objectUid.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
Expand Down Expand Up @@ -3028,7 +3052,7 @@ private void BuildLiteralProperties(IIndentedStringBuilder writer, XamlObjectDef
}
else if (member.Member.DeclaringType == null && member.Member.Name == "Name")
{
// This is a special case, where the declaring type is from the x: namespace,
// This is a special case, where the declaring type is from the x: namespace,
// but is considered of an unknown type. This can happen when providing the
// name of a control using x:Name instead of Name.
var hasNameProperty = HasProperty(objectDefinition.Type, "Name");
Expand Down Expand Up @@ -3195,7 +3219,7 @@ private void BuildChild(IIndentedStringBuilder writer, XamlMemberDefinition owne

if (contentOwner != null)
{
// This case is to support the layout switching for the ListViewBaseLayout, which is not
// This case is to support the layout switching for the ListViewBaseLayout, which is not
// a FrameworkTemplate. Thsi will need to be removed when this custom list view is removed.
var returnType = typeName == "ListViewBaseLayoutTemplate" ? "Uno.UI.Controls.Legacy.ListViewBaseLayout" : "_View";

Expand Down Expand Up @@ -3294,7 +3318,7 @@ private void BuildChild(IIndentedStringBuilder writer, XamlMemberDefinition owne
}
}

// Attached properties need to be expanded using the namespace, otherwise the resolution will be
// Attached properties need to be expanded using the namespace, otherwise the resolution will be
// performed at runtime at a higher cost.
propertyName = RewriteAttachedPropertyPath(propertyName);

Expand Down
10 changes: 5 additions & 5 deletions src/Uno.UI/UI/Xaml/DependencyObjectExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,18 +292,18 @@ internal static IDisposable RegisterDisposableNestedPropertyChangedCallback(this
/// Register for changes all dependency properties changes notifications for the specified instance.
/// </summary>
/// <param name="instance">The instance for which to observe properties changes</param>
/// <param name="callback">The callback</param>
/// <param name="handler">The callback</param>
/// <returns>A disposable that will unregister the callback when disposed.</returns>
internal static IDisposable RegisterInheritedPropertyChangedCallback(this object instance, ExplicitPropertyChangedCallback handler)
{
return GetStore(instance).RegisterInheritedPropertyChangedCallback(handler);
}

/// <summary>
/// Register for compiled bindinds updates progapation
/// Register for compiled bindings updates propagation
/// </summary>
/// <param name="instance">The instance for which to observe compiled bindings updates</param>
/// <param name="callback">The callback</param>
/// <param name="handler">The callback</param>
/// <returns>A disposable that will unregister the callback when disposed.</returns>
internal static IDisposable RegisterCompiledBindingsUpdateCallback(this object instance, Action handler)
=> GetStore(instance).RegisterCompiledBindingsUpdateCallback(handler);
Expand All @@ -312,8 +312,8 @@ internal static IDisposable RegisterCompiledBindingsUpdateCallback(this object i
/// Registers to parent changes.
/// </summary>
/// <param name="instance">The target dependency object</param>
/// <param name="key">A key to be passed to the callack parameter.</param>
/// <param name="callback">A callback to be called</param>
/// <param name="key">A key to be passed to the callback parameter.</param>
/// <param name="handler">A callback to be called</param>
/// <returns>A disposable that cancels the subscription.</returns>
internal static IDisposable RegisterParentChangedCallback(this DependencyObject instance, object key, ParentChangedCallback handler)
{
Expand Down

0 comments on commit 7ae1eb9

Please sign in to comment.