mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
Add member imports to lexer, assembler, and disassembler
This commit is contained in:
@@ -161,7 +161,7 @@ internal class AsmMarkupLoader
|
|||||||
foreach (var typeImport in Program.Imports.OfType<TypeImport>())
|
foreach (var typeImport in Program.Imports.OfType<TypeImport>())
|
||||||
{
|
{
|
||||||
var typeSchema = ResolveTypeFromQualifiedName(typeImport.QualifiedName);
|
var typeSchema = ResolveTypeFromQualifiedName(typeImport.QualifiedName);
|
||||||
_importTables.ImportedTypes.Add(typeSchema);
|
TrackImportedType(typeSchema);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var nsImport in Program.Imports.OfType<NamespaceImport>())
|
foreach (var nsImport in Program.Imports.OfType<NamespaceImport>())
|
||||||
@@ -215,7 +215,7 @@ internal class AsmMarkupLoader
|
|||||||
|
|
||||||
foreach (var constant in Program.Body.OfType<ConstantDirective>())
|
foreach (var constant in Program.Body.OfType<ConstantDirective>())
|
||||||
{
|
{
|
||||||
object constantValue;
|
object constantValue, persistData = null;
|
||||||
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
var constantTypeSchema = ResolveTypeFromQualifiedName(constant.TypeName);
|
||||||
|
|
||||||
if (constant is EncodedConstantDirective encodedConstant)
|
if (constant is EncodedConstantDirective encodedConstant)
|
||||||
@@ -226,6 +226,8 @@ internal class AsmMarkupLoader
|
|||||||
ReportError($"Failed to create an instance of '{constant.TypeName}' from '{encodedConstant.Content}'", constant);
|
ReportError($"Failed to create an instance of '{constant.TypeName}' from '{encodedConstant.Content}'", constant);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
persistData = encodedConstant.Content;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -249,11 +251,18 @@ internal class AsmMarkupLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var mode = constantTypeSchema.SupportsBinaryEncoding
|
MarkupConstantPersistMode mode;
|
||||||
? MarkupConstantPersistMode.Binary
|
if (constantTypeSchema.SupportsBinaryEncoding)
|
||||||
: MarkupConstantPersistMode.FromString;
|
{
|
||||||
|
mode = MarkupConstantPersistMode.Binary;
|
||||||
|
persistData = constantValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = MarkupConstantPersistMode.FromString;
|
||||||
|
}
|
||||||
|
|
||||||
var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode);
|
var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode, persistData);
|
||||||
_constants.Add(constant.Name, constantIndex);
|
_constants.Add(constant.Name, constantIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -308,8 +317,30 @@ internal class AsmMarkupLoader
|
|||||||
|
|
||||||
private LoadResult[] PrepareDependenciesTable()
|
private LoadResult[] PrepareDependenciesTable()
|
||||||
{
|
{
|
||||||
// TODO
|
LoadResult[] loadResultArray = LoadResult.EmptyList;
|
||||||
return [];
|
int length = 0;
|
||||||
|
if (_importTables != null)
|
||||||
|
{
|
||||||
|
foreach (LoadResult importedLoadResult in _importTables.ImportedLoadResults)
|
||||||
|
{
|
||||||
|
if (importedLoadResult != _loadResult)
|
||||||
|
++length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (length != 0)
|
||||||
|
{
|
||||||
|
loadResultArray = new LoadResult[length];
|
||||||
|
int index = 0;
|
||||||
|
foreach (LoadResult importedLoadResult in _importTables.ImportedLoadResults)
|
||||||
|
{
|
||||||
|
if (importedLoadResult != _loadResult)
|
||||||
|
{
|
||||||
|
loadResultArray[index] = importedLoadResult;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loadResultArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MarkupDataMapping[] PrepareDataMappingTable()
|
private MarkupDataMapping[] PrepareDataMappingTable()
|
||||||
|
|||||||
@@ -131,6 +131,40 @@ public class Disassembler
|
|||||||
|
|
||||||
yield return new TypeImport(new(namespacePrefix, typeImport.Name));
|
yield return new TypeImport(new(namespacePrefix, typeImport.Name));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
foreach (var constructorImport in _loadResult.ImportTables.ConstructorImports)
|
||||||
|
{
|
||||||
|
var typeName = GetQualifiedName(constructorImport.Owner);
|
||||||
|
var parameterTypeNames = constructorImport.ParameterTypes.Select(GetQualifiedName);
|
||||||
|
|
||||||
|
yield return new ConstructorImport(typeName, parameterTypeNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var methodImport in _loadResult.ImportTables.MethodImports)
|
||||||
|
{
|
||||||
|
var typeName = GetQualifiedName(methodImport.Owner);
|
||||||
|
var parameterTypeNames = methodImport.ParameterTypes.Select(GetQualifiedName);
|
||||||
|
|
||||||
|
yield return new MethodImport(typeName, methodImport.Name, parameterTypeNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<QualifiedTypeName, List<string>> namedMemberImports = new();
|
||||||
|
void GroupMemberImport(TypeSchema owner, string memberName)
|
||||||
|
{
|
||||||
|
var typeName = GetQualifiedName(owner);
|
||||||
|
if (!namedMemberImports.TryGetValue(typeName, out var currentTypeImports))
|
||||||
|
currentTypeImports = namedMemberImports[typeName] = new();
|
||||||
|
currentTypeImports.Add(memberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var propertyImport in _loadResult.ImportTables.PropertyImports)
|
||||||
|
GroupMemberImport(propertyImport.Owner, propertyImport.Name);
|
||||||
|
|
||||||
|
foreach (var eventImport in _loadResult.ImportTables.EventImports)
|
||||||
|
GroupMemberImport(eventImport.Owner, eventImport.Name);
|
||||||
|
|
||||||
|
foreach (var groupedImport in namedMemberImports)
|
||||||
|
yield return new NamedMemberImport(groupedImport.Key, groupedImport.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ConstantDirective> GetConstants()
|
public IEnumerable<ConstantDirective> GetConstants()
|
||||||
|
|||||||
@@ -58,6 +58,73 @@ partial class Lexer
|
|||||||
import = new TypeImport(typeNameResult.Value);
|
import = new TypeImport(typeNameResult.Value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "MBRS":
|
||||||
|
input = ConsumeWhitespace(input);
|
||||||
|
|
||||||
|
var memberTypeNameResult = ParseQualifiedTypeName(input);
|
||||||
|
input = memberTypeNameResult.Remainder;
|
||||||
|
if (!memberTypeNameResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid member import", ["Expected qualified type name"]);
|
||||||
|
|
||||||
|
input = Parse.Char('{')(input).Remainder;
|
||||||
|
|
||||||
|
var memberNamesResult = Parse.Ref(() => Identifier).DelimitedBy(Parse.Char(',').Token())(input);
|
||||||
|
input = memberNamesResult.Remainder;
|
||||||
|
if (!memberNamesResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid member import", ["Expected list of members to import"]);
|
||||||
|
|
||||||
|
input = Parse.Char('}')(input).Remainder;
|
||||||
|
|
||||||
|
import = new NamedMemberImport(memberTypeNameResult.Value, memberNamesResult.Value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "CTOR":
|
||||||
|
input = ConsumeWhitespace(input);
|
||||||
|
|
||||||
|
var ctorMemberTypeNameResult = ParseQualifiedTypeName(input);
|
||||||
|
input = ctorMemberTypeNameResult.Remainder;
|
||||||
|
if (!ctorMemberTypeNameResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid constructor import", ["Expected qualified type name"]);
|
||||||
|
|
||||||
|
input = Parse.Char('(')(input).Remainder;
|
||||||
|
|
||||||
|
var ctorParameterTypesResult = Parse.Ref(() => QualifiedTypeName).DelimitedBy(Parse.Char(',').Token())(input);
|
||||||
|
input = ctorParameterTypesResult.Remainder;
|
||||||
|
if (!ctorParameterTypesResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid constructor import", ["Expected constructor parameter types"]);
|
||||||
|
|
||||||
|
input = Parse.Char(')')(input).Remainder;
|
||||||
|
|
||||||
|
import = new ConstructorImport(ctorMemberTypeNameResult.Value, ctorParameterTypesResult.Value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "MTHD":
|
||||||
|
input = ConsumeWhitespace(input);
|
||||||
|
|
||||||
|
var mthdMemberTypeNameResult = ParseQualifiedTypeName(input);
|
||||||
|
input = mthdMemberTypeNameResult.Remainder;
|
||||||
|
if (!mthdMemberTypeNameResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid method import", ["Expected qualified type name"]);
|
||||||
|
|
||||||
|
input = Parse.Char('.')(input).Remainder;
|
||||||
|
|
||||||
|
var mthdNameResult = Identifier(input);
|
||||||
|
input = mthdNameResult.Remainder;
|
||||||
|
if (!mthdNameResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid method import", ["Expected method name"]);
|
||||||
|
|
||||||
|
input = Parse.Char('(')(input).Remainder;
|
||||||
|
|
||||||
|
var mthdParameterTypesResult = Parse.Ref(() => QualifiedTypeName).DelimitedBy(Parse.Char(',').Token())(input);
|
||||||
|
input = mthdParameterTypesResult.Remainder;
|
||||||
|
if (!mthdParameterTypesResult.WasSuccessful)
|
||||||
|
return Result.Failure<IImportDirective>(input, "Invalid constructor import", ["Expected constructor parameter types"]);
|
||||||
|
|
||||||
|
input = Parse.Char(')')(input).Remainder;
|
||||||
|
|
||||||
|
import = new MethodImport(mthdMemberTypeNameResult.Value, mthdNameResult.Value, mthdParameterTypesResult.Value);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Result.Failure<IImportDirective>(input, $"Unknown import type '{importTypeResult.Value}'", ["Expected 'ns', 'type'"]);
|
return Result.Failure<IImportDirective>(input, $"Unknown import type '{importTypeResult.Value}'", ["Expected 'ns', 'type'"]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
namespace Microsoft.Iris.Asm.Models;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Microsoft.Iris.Asm.Models;
|
||||||
|
|
||||||
public record NamespaceImport : ImportDirective
|
public record NamespaceImport : ImportDirective
|
||||||
{
|
{
|
||||||
@@ -25,3 +28,54 @@ public record TypeImport : ImportDirective
|
|||||||
|
|
||||||
public override string ToString() => $"{base.ToString()} {QualifiedName}";
|
public override string ToString() => $"{base.ToString()} {QualifiedName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Imports many members that can be specified by solely their name.
|
||||||
|
/// </summary>
|
||||||
|
public record NamedMemberImport : ImportDirective
|
||||||
|
{
|
||||||
|
public NamedMemberImport(QualifiedTypeName qualifiedName, IEnumerable<string> memberNames) : base("mbrs")
|
||||||
|
{
|
||||||
|
QualifiedName = qualifiedName;
|
||||||
|
MemberNames = memberNames.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public QualifiedTypeName QualifiedName { get; init; }
|
||||||
|
|
||||||
|
public List<string> MemberNames { get; init; }
|
||||||
|
|
||||||
|
public override string ToString() => $"{base.ToString()} {QualifiedName}{{{string.Join(", ", MemberNames)}}}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ConstructorImport : ImportDirective
|
||||||
|
{
|
||||||
|
public ConstructorImport(QualifiedTypeName qualifiedName, IEnumerable<QualifiedTypeName> parameterTypes) : base("ctor")
|
||||||
|
{
|
||||||
|
QualifiedName = qualifiedName;
|
||||||
|
ParameterTypes = parameterTypes.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public QualifiedTypeName QualifiedName { get; init; }
|
||||||
|
|
||||||
|
public IEnumerable<QualifiedTypeName> ParameterTypes { get; init; }
|
||||||
|
|
||||||
|
public override string ToString() => $"{base.ToString()} {QualifiedName}.({string.Join(", ", ParameterTypes)})";
|
||||||
|
}
|
||||||
|
|
||||||
|
public record MethodImport : ImportDirective
|
||||||
|
{
|
||||||
|
public MethodImport(QualifiedTypeName qualifiedName, string methodName, IEnumerable<QualifiedTypeName> parameterTypes) : base("mthd")
|
||||||
|
{
|
||||||
|
QualifiedName = qualifiedName;
|
||||||
|
MethodName = methodName;
|
||||||
|
ParameterTypes = parameterTypes.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public QualifiedTypeName QualifiedName { get; init; }
|
||||||
|
|
||||||
|
public string MethodName { get; init; }
|
||||||
|
|
||||||
|
public IEnumerable<QualifiedTypeName> ParameterTypes { get; init; }
|
||||||
|
|
||||||
|
public override string ToString() => $"{base.ToString()} {QualifiedName}.{MethodName}({string.Join(", ", ParameterTypes)})";
|
||||||
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ public class Assembly(ITestOutputHelper output)
|
|||||||
.import-type Text
|
.import-type Text
|
||||||
.import-type Color
|
.import-type Color
|
||||||
.import-type Font
|
.import-type Font
|
||||||
|
.import-mbrs UI{Locals, Content}
|
||||||
|
.import-mbrs Text{Color, Content, Font}
|
||||||
|
|
||||||
.constant const0 = Color(255, 255, 0, 0)
|
.constant const0 = Color(255, 255, 0, 0)
|
||||||
.constant const1 = String(Howdy from Microsoft.Iris!)
|
.constant const1 = String(Howdy from Microsoft.Iris!)
|
||||||
@@ -35,8 +37,6 @@ public class Assembly(ITestOutputHelper output)
|
|||||||
.constant const3 = Color(255, 0, 0, 255)
|
.constant const3 = Color(255, 0, 0, 255)
|
||||||
.constant const4 = Font(JetBrains Mono)
|
.constant const4 = Font(JetBrains Mono)
|
||||||
.constant const5 = String(This is some blue text)
|
.constant const5 = String(This is some blue text)
|
||||||
.constant xmlTest = <FlowLayout Orientation="Vertical" Spacing="50,0" />
|
|
||||||
|
|
||||||
.section object
|
.section object
|
||||||
|
|
||||||
Default_cont:
|
Default_cont:
|
||||||
@@ -69,7 +69,7 @@ Alt_locl:
|
|||||||
output.WriteLine(ast.ToString());
|
output.WriteLine(ast.ToString());
|
||||||
|
|
||||||
Assert.NotNull(ast);
|
Assert.NotNull(ast);
|
||||||
Assert.Equal(19, ast.Directives.Count());
|
Assert.Equal(20, ast.Directives.Count());
|
||||||
Assert.Equal(24, ast.Code.Count());
|
Assert.Equal(24, ast.Code.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user