mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] First pass at script decompilation
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
using Microsoft.Iris.Markup;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.Iris.Markup;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Microsoft.Iris.DecompXml.Mock;
|
||||
|
||||
internal class IrisConstantExpression : IrisExpression, IReturnValueProvider
|
||||
@@ -19,16 +24,17 @@ internal class IrisConstantExpression : IrisExpression, IReturnValueProvider
|
||||
|
||||
public TypeSchema ReturnType => TypeSchema;
|
||||
|
||||
public override string Decompile(DecompileContext context)
|
||||
public override ExpressionSyntax ToSyntax(DecompileContext context)
|
||||
{
|
||||
if (TypeSchema.IsEnum)
|
||||
return $"{context.GetQualifiedName(TypeSchema)}.{Value}";
|
||||
|
||||
return Value switch
|
||||
{
|
||||
string str => str,
|
||||
IStringEncodable strEnc => strEnc.EncodeString(),
|
||||
_ => Value?.ToString() ?? "null",
|
||||
Enum enumValue => MemberAccessExpression(
|
||||
SyntaxKind.SimpleMemberAccessExpression,
|
||||
IdentifierName(context.GetQualifiedName(TypeSchema).ToString()),
|
||||
IdentifierName(Value.ToString())
|
||||
),
|
||||
|
||||
_ => ToSyntax(Value, context)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
using Microsoft.Iris.Asm;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.Iris.Asm;
|
||||
using Microsoft.Iris.Markup;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Microsoft.Iris.DecompXml.Mock;
|
||||
|
||||
internal class IrisExpression : Expression
|
||||
internal abstract class IrisExpression : Expression
|
||||
{
|
||||
public virtual string Decompile(DecompileContext context) => ToString();
|
||||
public virtual string Decompile(DecompileContext context) => ToSyntax(context).ToString();
|
||||
|
||||
public abstract ExpressionSyntax ToSyntax(DecompileContext context);
|
||||
|
||||
public static Expression Wrap(object p)
|
||||
{
|
||||
@@ -15,7 +23,7 @@ internal class IrisExpression : Expression
|
||||
null => Constant(null),
|
||||
Expression expr => expr,
|
||||
Disassembler.RawConstantInfo constantInfo => new IrisConstantExpression(constantInfo.Value, constantInfo.Type),
|
||||
Markup.SymbolReference symbolRef => Constant(symbolRef),
|
||||
SymbolReference symbolRef => Constant(symbolRef),
|
||||
|
||||
_ => throw new NotImplementedException($"Unable to wrap '{p}' in an expression")
|
||||
};
|
||||
@@ -27,4 +35,25 @@ internal class IrisExpression : Expression
|
||||
? irisExpr.Decompile(context)
|
||||
: expr.ToString();
|
||||
}
|
||||
|
||||
public static ExpressionSyntax ToSyntax(object obj, DecompileContext context)
|
||||
{
|
||||
return obj switch
|
||||
{
|
||||
null => LiteralExpression(SyntaxKind.NullLiteralExpression),
|
||||
int intValue => LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(intValue)),
|
||||
string strValue => LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(strValue)),
|
||||
IStringEncodable strEnc => ParseExpression(strEnc.EncodeString()),
|
||||
|
||||
Disassembler.RawConstantInfo constantInfo => new IrisConstantExpression(constantInfo.Value, constantInfo.Type).ToSyntax(context),
|
||||
SymbolReference symbolRef => IdentifierName(symbolRef.Symbol),
|
||||
TypeSchema typeSchema => IdentifierName(context.GetQualifiedName(typeSchema).ToString()),
|
||||
|
||||
IrisExpression irisExpr => irisExpr.ToSyntax(context),
|
||||
Expression expr => ParseExpression(expr.ToString()),
|
||||
ExpressionSyntax exprSyn => exprSyn,
|
||||
|
||||
_ => IdentifierName(obj.ToString())
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using Microsoft.Iris.Markup;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.Iris.Markup;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Microsoft.Iris.DecompXml.Mock;
|
||||
|
||||
@@ -29,27 +31,22 @@ internal class IrisMethodCallExpression : IrisExpression, IArgumentProvider, IRe
|
||||
|
||||
public Expression GetArgument(int index) => _arguments[index];
|
||||
|
||||
public override string Decompile(DecompileContext context)
|
||||
public override ExpressionSyntax ToSyntax(DecompileContext context)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
|
||||
if (Target is null)
|
||||
var targetExpression = Target switch
|
||||
{
|
||||
var qfn = context.GetQualifiedName(Method.Owner);
|
||||
sb.Append(qfn);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Decompile(Target, context));
|
||||
}
|
||||
null => IdentifierName(context.GetQualifiedName(Method.Owner).ToString()),
|
||||
IrisExpression irisExpr => irisExpr.ToSyntax(context),
|
||||
_ => IdentifierName(Target.ToString())
|
||||
};
|
||||
|
||||
sb.Append('.');
|
||||
sb.Append(Method.Name);
|
||||
var methodExpression = MemberAccessExpression(CodeAnalysis.CSharp.SyntaxKind.SimpleMemberAccessExpression,
|
||||
targetExpression, IdentifierName(Method.Name));
|
||||
|
||||
sb.Append('(');
|
||||
sb.Append(string.Join(", ", _arguments.Select(x => Decompile(x, context))));
|
||||
sb.Append(')');
|
||||
var argumentExpressions = _arguments
|
||||
.Select(expr => ToSyntax(expr, context))
|
||||
.Select(Argument);
|
||||
|
||||
return sb.ToString();
|
||||
return InvocationExpression(methodExpression, ArgumentList([..argumentExpressions]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.Iris.Markup;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.Iris.Markup;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||
|
||||
namespace Microsoft.Iris.DecompXml.Mock;
|
||||
|
||||
@@ -20,24 +22,18 @@ internal class IrisPropertyExpression : IrisExpression, IReturnValueProvider
|
||||
|
||||
public TypeSchema ReturnType => Property.PropertyType;
|
||||
|
||||
|
||||
public override string Decompile(DecompileContext context)
|
||||
public override ExpressionSyntax ToSyntax(DecompileContext context)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
|
||||
if (Target is null)
|
||||
var targetExpression = Target switch
|
||||
{
|
||||
var qfn = context.GetQualifiedName(Property.Owner);
|
||||
sb.Append(qfn);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(Decompile(Target, context));
|
||||
}
|
||||
null => IdentifierName(context.GetQualifiedName(Property.Owner).ToString()),
|
||||
IrisExpression irisExpr => irisExpr.ToSyntax(context),
|
||||
_ => IdentifierName(Target.ToString())
|
||||
};
|
||||
|
||||
sb.Append('.');
|
||||
sb.Append(Property.Name);
|
||||
var propertyAccessExpression = MemberAccessExpression(CodeAnalysis.CSharp.SyntaxKind.SimpleMemberAccessExpression,
|
||||
targetExpression, IdentifierName(Property.Name));
|
||||
|
||||
return sb.ToString();
|
||||
return propertyAccessExpression;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user