mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Add special handling for SingleModelItem
This commit is contained in:
@@ -1,9 +1,12 @@
|
|||||||
using Microsoft.CodeAnalysis.CSharp;
|
using Microsoft.CodeAnalysis.CSharp;
|
||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Microsoft.Iris.Asm;
|
using Microsoft.Iris.Asm;
|
||||||
|
using Microsoft.Iris.Asm.Models;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DecompXml.Mock;
|
namespace Microsoft.Iris.DecompXml.Mock;
|
||||||
@@ -40,11 +43,30 @@ internal class IrisExpression
|
|||||||
if (TryMapPredefinedType(type, out var kind))
|
if (TryMapPredefinedType(type, out var kind))
|
||||||
return PredefinedType(Token(kind));
|
return PredefinedType(Token(kind));
|
||||||
|
|
||||||
return IdentifierName(context.GetQualifiedName(type).ToString());
|
var typeName = context.GetQualifiedName(type);
|
||||||
|
|
||||||
|
if (type.Name.StartsWith("SingletonModelItem"))
|
||||||
|
{
|
||||||
|
// Special handling for this weird wrapper type
|
||||||
|
var genericName = ParseGenericType(typeName);
|
||||||
|
var innerFullTypeName = genericName.TypeArgumentList.Arguments[0].ToString();
|
||||||
|
|
||||||
|
// Resolve namespace to prefix
|
||||||
|
var nsEndIndex = innerFullTypeName.LastIndexOf('.');
|
||||||
|
var innerTypeName = innerFullTypeName[(nsEndIndex + 1)..];
|
||||||
|
var ns = innerFullTypeName[..nsEndIndex];
|
||||||
|
|
||||||
|
var innerType = context.ImportTables.TypeImports
|
||||||
|
.Where(t => t.Name == innerTypeName || t.AlternateName == innerTypeName)
|
||||||
|
.FirstOrDefault(t => (t.Owner as AssemblyLoadResult)?.Namespace == ns);
|
||||||
|
|
||||||
|
typeName = context.GetQualifiedName(innerType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IdentifierName(typeName.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IdentifierNameSyntax ToSyntax(SymbolReference symbolRef) =>
|
public static IdentifierNameSyntax ToSyntax(SymbolReference symbolRef) => IdentifierName(symbolRef.Symbol);
|
||||||
IdentifierName(symbolRef.Symbol);
|
|
||||||
|
|
||||||
public static ExpressionSyntax ToSyntax(object obj, TypeSchema type, uint offset, DecompileContext context)
|
public static ExpressionSyntax ToSyntax(object obj, TypeSchema type, uint offset, DecompileContext context)
|
||||||
{
|
{
|
||||||
@@ -90,4 +112,22 @@ internal class IrisExpression
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static GenericNameSyntax ParseGenericType(QualifiedTypeName typeName)
|
||||||
|
{
|
||||||
|
Regex rxGeneric = new(@"([A-z_:]\w*)`(\d+)\[(.+)\]");
|
||||||
|
var genericMatch = rxGeneric.Match(typeName.TypeName);
|
||||||
|
if (!genericMatch.Success)
|
||||||
|
throw new ArgumentException("Invalid generic");
|
||||||
|
|
||||||
|
var unqualifiedTypeName = genericMatch.Groups[1].Value;
|
||||||
|
var typeArgCount = int.Parse(genericMatch.Groups[2].Value);
|
||||||
|
var typeArgNames = genericMatch.Groups[3].Value
|
||||||
|
.Split(',')
|
||||||
|
.Select(IdentifierName);
|
||||||
|
|
||||||
|
// TODO: Handle nested generics
|
||||||
|
var trimmedTypeName = $"{typeName.NamespacePrefix}:{unqualifiedTypeName}";
|
||||||
|
return GenericName(Identifier(trimmedTypeName), TypeArgumentList([.. typeArgNames]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||||||
using Microsoft.Iris.Asm;
|
using Microsoft.Iris.Asm;
|
||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DecompXml.Mock;
|
namespace Microsoft.Iris.DecompXml.Mock;
|
||||||
@@ -52,7 +53,7 @@ internal record IrisObject(object Object, TypeSchema Type)
|
|||||||
|
|
||||||
if (expr is MemberAccessExpressionSyntax memberAccessExpression)
|
if (expr is MemberAccessExpressionSyntax memberAccessExpression)
|
||||||
{
|
{
|
||||||
// TODO: Handle member access on instance methods
|
// TODO: Handle member access on instances
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var sourceExpr = (IdentifierNameSyntax)memberAccessExpression.Expression;
|
var sourceExpr = (IdentifierNameSyntax)memberAccessExpression.Expression;
|
||||||
@@ -90,6 +91,35 @@ internal record IrisObject(object Object, TypeSchema Type)
|
|||||||
_ => throw new System.NotImplementedException(),
|
_ => throw new System.NotImplementedException(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else if (expr is InvocationExpressionSyntax invocationExpression)
|
||||||
|
{
|
||||||
|
// TODO: Handle invocation of instance methods
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var sourceExpr = invocationExpression.Expression;
|
||||||
|
|
||||||
|
List<NameSyntax> names = [];
|
||||||
|
while (sourceExpr is MemberAccessExpressionSyntax innerSourceExpr)
|
||||||
|
{
|
||||||
|
names.Add(innerSourceExpr.Name);
|
||||||
|
sourceExpr = innerSourceExpr.Expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourceTypeName = QualifiedTypeName.Parse(sourceExpr.ToString());
|
||||||
|
var sourceType = ctx.GetImportedType(sourceTypeName);
|
||||||
|
|
||||||
|
var memberName = names[^1].ToString();
|
||||||
|
|
||||||
|
// Try to disambiguate overloads using number of parameters
|
||||||
|
var parameterCount = invocationExpression.ArgumentList.Arguments.Count;
|
||||||
|
|
||||||
|
var method = sourceType.Methods.FirstOrDefault(
|
||||||
|
m => m.Name == memberName && m.ParameterTypes.Length == parameterCount);
|
||||||
|
|
||||||
|
return method?.ReturnType;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<Boolean Name="ShowZunePassTracks" Boolean="true" />
|
<Boolean Name="ShowZunePassTracks" Boolean="true" />
|
||||||
</Properties>
|
</Properties>
|
||||||
<Locals>
|
<Locals>
|
||||||
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance}" />
|
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:TransportControls.Instance}" />
|
||||||
<zuneUI:SignIn Name="SignIn" SignIn="{zuneUI:SignIn.Instance}" />
|
<zuneUI:SignIn Name="SignIn" SignIn="{zuneUI:SignIn.Instance}" />
|
||||||
</Locals>
|
</Locals>
|
||||||
<Scripts>
|
<Scripts>
|
||||||
@@ -55,7 +55,7 @@ bool IsQuickMix()
|
|||||||
</Properties>
|
</Properties>
|
||||||
<Locals>
|
<Locals>
|
||||||
<Window Name="Window" />
|
<Window Name="Window" />
|
||||||
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance}" />
|
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:TransportControls.Instance}" />
|
||||||
<SelectionManager Name="SelectionManager" />
|
<SelectionManager Name="SelectionManager" />
|
||||||
<contentList:NavigateIntoIndexRequest Name="NavigateIntoArgs" />
|
<contentList:NavigateIntoIndexRequest Name="NavigateIntoArgs" />
|
||||||
<nowPlayingLand:NowPlayingListModel Name="NowPlayingListModel" Page="{Page}" />
|
<nowPlayingLand:NowPlayingListModel Name="NowPlayingListModel" Page="{Page}" />
|
||||||
@@ -126,8 +126,8 @@ UI.CreateInterestOnFocus = false;
|
|||||||
ShowMPContent.Value = nowPlayingLand:NowPlayingPersistentState.ShowZunePassTracks;
|
ShowMPContent.Value = nowPlayingLand:NowPlayingPersistentState.ShowZunePassTracks;
|
||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack)]
|
[DeclareTrigger(zuneUI:TransportControls.Instance.CurrentTrack)]
|
||||||
CurrentTrack = #zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack #;
|
CurrentTrack = #zuneUI:TransportControls.Instance.CurrentTrack #;
|
||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(TransportControls.Playing), DeclareTrigger(TransportControls.PlayingVideo), DeclareTrigger(Page.SlideShowState.Play), DeclareTrigger(MiniMode.InCompactMode), DeclareTrigger(MiniMode.InPopupMode), DeclareTrigger(Window.WindowState)]
|
[DeclareTrigger(TransportControls.Playing), DeclareTrigger(TransportControls.PlayingVideo), DeclareTrigger(Page.SlideShowState.Play), DeclareTrigger(MiniMode.InCompactMode), DeclareTrigger(MiniMode.InPopupMode), DeclareTrigger(Window.WindowState)]
|
||||||
@@ -272,7 +272,7 @@ ActionContainer.Visible = #SaveAsPlaylistButton.Visible # || #ShowMPContentCheck
|
|||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(CurrentlyPlayingTrackMixAvailability.Available)]
|
[DeclareTrigger(CurrentlyPlayingTrackMixAvailability.Available)]
|
||||||
object track = zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack;
|
object track = zuneUI:TransportControls.Instance.CurrentTrack;
|
||||||
if ((Page.ShowMixOnEntry && track != null) && (Page.InitialPlaybackID == track.PlaybackID) && #CurrentlyPlayingTrackMixAvailability.Available #)
|
if ((Page.ShowMixOnEntry && track != null) && (Page.InitialPlaybackID == track.PlaybackID) && #CurrentlyPlayingTrackMixAvailability.Available #)
|
||||||
{
|
{
|
||||||
CurrentlyPlayingTrackMixAvailability.UpdateMixSeed.Invoke();
|
CurrentlyPlayingTrackMixAvailability.UpdateMixSeed.Invoke();
|
||||||
@@ -620,7 +620,7 @@ bool IsQuickMix()
|
|||||||
</Properties>
|
</Properties>
|
||||||
<Locals>
|
<Locals>
|
||||||
<Window Name="Window" />
|
<Window Name="Window" />
|
||||||
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance}" />
|
<zuneUI:TransportControls Name="TransportControls" TransportControls="{zuneUI:TransportControls.Instance}" />
|
||||||
<nonClientControls:WindowState Name="WindowState" />
|
<nonClientControls:WindowState Name="WindowState" />
|
||||||
<iris:Command Name="ZoomScale0" Description="{zuneUI:Shell.LoadString(zuneUI:StringId.IDS_VIDEO_ZOOM_FULL)}" />
|
<iris:Command Name="ZoomScale0" Description="{zuneUI:Shell.LoadString(zuneUI:StringId.IDS_VIDEO_ZOOM_FULL)}" />
|
||||||
<iris:Command Name="ZoomScale1" Description="{zuneUI:Shell.LoadString(zuneUI:StringId.IDS_VIDEO_ZOOM_NONE)}" />
|
<iris:Command Name="ZoomScale1" Description="{zuneUI:Shell.LoadString(zuneUI:StringId.IDS_VIDEO_ZOOM_NONE)}" />
|
||||||
@@ -678,7 +678,7 @@ if (playingVideo)
|
|||||||
((float)(wndWidth)) / ((float)(naturalWidth));
|
((float)(wndWidth)) / ((float)(naturalWidth));
|
||||||
object scaleY = (float)(wndHeight) / (float)(naturalHeight);
|
object scaleY = (float)(wndHeight) / (float)(naturalHeight);
|
||||||
((float)(wndHeight)) / ((float)(naturalHeight));
|
((float)(wndHeight)) / ((float)(naturalHeight));
|
||||||
object scale = system:Math.Min(scaleX, scaleY);
|
int scale = system:Math.Min(scaleX, scaleY);
|
||||||
maxVideoSizeX = #TransportControls.ZoomScaleFactor # * naturalWidth;
|
maxVideoSizeX = #TransportControls.ZoomScaleFactor # * naturalWidth;
|
||||||
maxVideoSizeY = TransportControls.ZoomScaleFactor * naturalHeight;
|
maxVideoSizeY = TransportControls.ZoomScaleFactor * naturalHeight;
|
||||||
if (maxVideoSizeY + 50 > wndHeight || maxVideoSizeX + 50 > wndWidth)
|
if (maxVideoSizeY + 50 > wndHeight || maxVideoSizeX + 50 > wndWidth)
|
||||||
@@ -875,7 +875,7 @@ else
|
|||||||
{
|
{
|
||||||
SelectionManager selectionManager = (SelectionManager)value;
|
SelectionManager selectionManager = (SelectionManager)value;
|
||||||
object insertAt = InsertIndex.Value;
|
object insertAt = InsertIndex.Value;
|
||||||
zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.ReorderNowPlaying(selectionManager.SelectedIndices, insertAt);
|
zuneUI:TransportControls.Instance.ReorderNowPlaying(selectionManager.SelectedIndices, insertAt);
|
||||||
}
|
}
|
||||||
]]></Script>
|
]]></Script>
|
||||||
</Scripts>
|
</Scripts>
|
||||||
@@ -936,8 +936,8 @@ else
|
|||||||
</Properties>
|
</Properties>
|
||||||
<Scripts>
|
<Scripts>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.ErrorCount)]
|
[DeclareTrigger(zuneUI:TransportControls.Instance.ErrorCount)]
|
||||||
ErrorCode = zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.GetLibraryErrorCode(Model);
|
ErrorCode = zuneUI:TransportControls.Instance.GetLibraryErrorCode(Model);
|
||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(RowModel.IsNowPlaying)]
|
[DeclareTrigger(RowModel.IsNowPlaying)]
|
||||||
@@ -996,8 +996,8 @@ SignInButton.Visible = #RowModel.ButtonState #.ChosenValue # == "SignIn";
|
|||||||
Upsell.Visible = util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eSubscription) && RowModel.ButtonState.ChosenValue == "Upsell";
|
Upsell.Visible = util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eSubscription) && RowModel.ButtonState.ChosenValue == "Upsell";
|
||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack)]
|
[DeclareTrigger(zuneUI:TransportControls.Instance.CurrentTrack)]
|
||||||
RowModel.IsNowPlaying = Model == #zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack #;
|
RowModel.IsNowPlaying = Model == #zuneUI:TransportControls.Instance.CurrentTrack #;
|
||||||
]]></Script>
|
]]></Script>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(RowModel.IsNowPlaying), DeclareTrigger(RowModel.ForceNonMarketplace)]
|
[DeclareTrigger(RowModel.IsNowPlaying), DeclareTrigger(RowModel.ForceNonMarketplace)]
|
||||||
@@ -1319,8 +1319,8 @@ if (ListModel.SelectionManager != null && ListModel.SelectionManager.IsSelected(
|
|||||||
</Locals>
|
</Locals>
|
||||||
<Scripts>
|
<Scripts>
|
||||||
<Script><![CDATA[
|
<Script><![CDATA[
|
||||||
[DeclareTrigger(zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack)]
|
[DeclareTrigger(zuneUI:TransportControls.Instance.CurrentTrack)]
|
||||||
object track = #zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack #;
|
object track = #zuneUI:TransportControls.Instance.CurrentTrack #;
|
||||||
if (LibraryAlbumInfo != null)
|
if (LibraryAlbumInfo != null)
|
||||||
{
|
{
|
||||||
Class.DisposeOwnedObject(LibraryAlbumInfo);
|
Class.DisposeOwnedObject(LibraryAlbumInfo);
|
||||||
@@ -1513,7 +1513,7 @@ if (RotateInfo.Enabled)
|
|||||||
[DeclareTrigger(NowPlayingBackgroundHelper.Visible)]
|
[DeclareTrigger(NowPlayingBackgroundHelper.Visible)]
|
||||||
MPTrackQuery.Enabled = false;
|
MPTrackQuery.Enabled = false;
|
||||||
MPTrackQuery.Id = null;
|
MPTrackQuery.Id = null;
|
||||||
object currentTrack = zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack;
|
object currentTrack = zuneUI:TransportControls.Instance.CurrentTrack;
|
||||||
if (#NowPlayingBackgroundHelper.Visible # && NowPlayingBackgroundHelper.Visible || !currentTrack.IsInVisibleCollection && util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eMusic))
|
if (#NowPlayingBackgroundHelper.Visible # && NowPlayingBackgroundHelper.Visible || !currentTrack.IsInVisibleCollection && util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eMusic))
|
||||||
{
|
{
|
||||||
MPTrackQuery.Id = TrackId.ToString();
|
MPTrackQuery.Id = TrackId.ToString();
|
||||||
@@ -1530,7 +1530,7 @@ ArtistQuery.Enabled = false;
|
|||||||
ArtistQuery.Id = null;
|
ArtistQuery.Id = null;
|
||||||
TopListenersQuery.Enabled = false;
|
TopListenersQuery.Enabled = false;
|
||||||
TopListenersQuery.ArtistId = null;
|
TopListenersQuery.ArtistId = null;
|
||||||
object currentTrack = zuneUI:SingletonModelItem`1[ZuneUI.TransportControls].Instance.CurrentTrack;
|
object currentTrack = zuneUI:TransportControls.Instance.CurrentTrack;
|
||||||
if (((!zuneUI:GuidHelper.IsEmpty(ArtistId) && #NowPlayingBackgroundHelper.Visible # && util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eMusic) && configuration:ClientConfiguration.Playback.ShowNowPlayingClipAnimations) && (iris:Application.RenderingQuality == iris:RenderingQuality.MaxQuality)) && (currentTrack != null) && currentTrack.IsMusic)
|
if (((!zuneUI:GuidHelper.IsEmpty(ArtistId) && #NowPlayingBackgroundHelper.Visible # && util:FeatureEnablement.IsFeatureEnabled(zuneDBApi:Features.eMusic) && configuration:ClientConfiguration.Playback.ShowNowPlayingClipAnimations) && (iris:Application.RenderingQuality == iris:RenderingQuality.MaxQuality)) && (currentTrack != null) && currentTrack.IsMusic)
|
||||||
{
|
{
|
||||||
ArtistPhotosQuery.Id = ArtistId.ToString();
|
ArtistPhotosQuery.Id = ArtistId.ToString();
|
||||||
|
|||||||
Reference in New Issue
Block a user