diff --git a/Schema Tests/SchemaStructureParserTests.cs b/Schema Tests/SchemaStructureParserTests.cs index 7dd8227..15196a2 100644 --- a/Schema Tests/SchemaStructureParserTests.cs +++ b/Schema Tests/SchemaStructureParserTests.cs @@ -31,7 +31,7 @@ public class ByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.BYTE, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -63,7 +63,7 @@ public class SByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.SBYTE, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -95,7 +95,7 @@ public class Int16Wrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.INT16, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -134,7 +134,7 @@ public class EnumWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.ENUM, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(true, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UINT16, primitiveType.AltFormat); } @@ -158,12 +158,12 @@ public class ArrayWrapper { Assert.AreEqual(TypeKind.Array, memberType.TypeSymbol.TypeKind); var arrayType = (memberType as ISequenceMemberType)!; - Assert.AreEqual(SequenceType.ARRAY, arrayType.SequenceType); - Assert.AreEqual(SequenceLengthSourceType.READONLY, arrayType.LengthSourceType); + Assert.AreEqual(SequenceType.MUTABLE_ARRAY, arrayType.SequenceTypeInfo.SequenceType); + Assert.AreEqual(SequenceLengthSourceType.READ_ONLY, arrayType.LengthSourceType); var primitiveType = (arrayType.ElementType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.INT32, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -187,12 +187,12 @@ public class CharWrapper { Assert.AreEqual(TypeKind.Array, memberType.TypeSymbol.TypeKind); var arrayType = (memberType as ISequenceMemberType)!; - Assert.AreEqual(SequenceType.ARRAY, arrayType.SequenceType); - Assert.AreEqual(SequenceLengthSourceType.READONLY, arrayType.LengthSourceType); + Assert.AreEqual(SequenceType.MUTABLE_ARRAY, arrayType.SequenceTypeInfo.SequenceType); + Assert.AreEqual(SequenceLengthSourceType.READ_ONLY, arrayType.LengthSourceType); var primitiveType = (arrayType.ElementType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.CHAR, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -224,7 +224,7 @@ public class ByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.BYTE, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -256,7 +256,7 @@ public class ByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.BYTE, primitiveType.PrimitiveType); - Assert.AreEqual(false, primitiveType.IsReadonly); + Assert.AreEqual(false, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -288,7 +288,7 @@ public class ByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.BYTE, primitiveType.PrimitiveType); - Assert.AreEqual(true, primitiveType.IsReadonly); + Assert.AreEqual(true, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } @@ -320,7 +320,7 @@ public class ByteWrapper { var primitiveType = (memberType as IPrimitiveMemberType)!; Assert.AreEqual(SchemaPrimitiveType.BYTE, primitiveType.PrimitiveType); - Assert.AreEqual(true, primitiveType.IsReadonly); + Assert.AreEqual(true, primitiveType.IsReadOnly); Assert.AreEqual(false, primitiveType.UseAltFormat); Assert.AreEqual(SchemaNumberType.UNDEFINED, primitiveType.AltFormat); } diff --git a/Schema/src/binary/BinarySchemaStructureParser.cs b/Schema/src/binary/BinarySchemaStructureParser.cs index 1d60179..de6d563 100644 --- a/Schema/src/binary/BinarySchemaStructureParser.cs +++ b/Schema/src/binary/BinarySchemaStructureParser.cs @@ -75,7 +75,7 @@ public interface ISchemaMember { public interface IMemberType { ITypeInfo TypeInfo { get; } ITypeSymbol TypeSymbol { get; } - bool IsReadonly { get; } + bool IsReadOnly { get; } } public interface IPrimitiveMemberType : IMemberType { @@ -143,8 +143,12 @@ public interface IStringType : IMemberType { } public enum SequenceType { - ARRAY, - LIST, + MUTABLE_ARRAY, + IMMUTABLE_ARRAY, + MUTABLE_LIST, + READ_ONLY_LIST, + MUTABLE_SEQUENCE, + READ_ONLY_SEQUENCE, } public enum SequenceLengthSourceType { @@ -152,15 +156,13 @@ public enum SequenceLengthSourceType { IMMEDIATE_VALUE, OTHER_MEMBER, CONST_LENGTH, - READONLY, + READ_ONLY, UNTIL_END_OF_STREAM, } public interface ISequenceMemberType : IMemberType { ISequenceTypeInfo SequenceTypeInfo { get; } - SequenceType SequenceType { get; } - SequenceLengthSourceType LengthSourceType { get; } SchemaIntegerType ImmediateLengthType { get; } ISchemaMember? LengthMember { get; } @@ -556,7 +558,7 @@ memberType is BinarySchemaStructureParser.PrimitiveMemberType Rules.NotSupported)); } - if (memberTypeInfo.IsReadonly) { + if (memberTypeInfo.IsReadOnly) { diagnostics.Add( Rules.CreateDiagnostic(memberSymbol, Rules.UnexpectedAttribute)); @@ -656,7 +658,7 @@ public class PrimitiveMemberType : IPrimitiveMemberType { public IPrimitiveTypeInfo PrimitiveTypeInfo { get; set; } public ITypeInfo TypeInfo => PrimitiveTypeInfo; public ITypeSymbol TypeSymbol => TypeInfo.TypeSymbol; - public bool IsReadonly => this.TypeInfo.IsReadonly; + public bool IsReadOnly => this.TypeInfo.IsReadOnly; public SchemaPrimitiveType PrimitiveType => this.PrimitiveTypeInfo.PrimitiveType; @@ -673,7 +675,7 @@ public class StructureMemberType : IStructureMemberType { public IStructureTypeInfo StructureTypeInfo { get; set; } public ITypeInfo TypeInfo => StructureTypeInfo; public ITypeSymbol TypeSymbol => TypeInfo.TypeSymbol; - public bool IsReadonly => this.TypeInfo.IsReadonly; + public bool IsReadOnly => this.TypeInfo.IsReadOnly; public bool IsReferenceType { get; set; } public bool IsChild { get; set; } @@ -685,7 +687,7 @@ public class GenericMemberType : IGenericMemberType { public IGenericTypeInfo GenericTypeInfo { get; set; } public ITypeInfo TypeInfo => GenericTypeInfo; public ITypeSymbol TypeSymbol => TypeInfo.TypeSymbol; - public bool IsReadonly => this.TypeInfo.IsReadonly; + public bool IsReadOnly => this.TypeInfo.IsReadOnly; } public class IfBoolean : IIfBoolean { @@ -702,7 +704,7 @@ public class Offset : IOffset { public class StringType : IStringType { public ITypeInfo TypeInfo { get; set; } public ITypeSymbol TypeSymbol => TypeInfo.TypeSymbol; - public bool IsReadonly => this.TypeInfo.IsReadonly; + public bool IsReadOnly => this.TypeInfo.IsReadOnly; public StringLengthSourceType LengthSourceType { get; set; } public SchemaIntegerType ImmediateLengthType { get; set; } @@ -714,9 +716,7 @@ public class SequenceMemberType : ISequenceMemberType { public ISequenceTypeInfo SequenceTypeInfo { get; set; } public ITypeInfo TypeInfo => SequenceTypeInfo; public ITypeSymbol TypeSymbol => TypeInfo.TypeSymbol; - public bool IsReadonly => this.TypeInfo.IsReadonly; - - public SequenceType SequenceType { get; set; } + public bool IsReadOnly => this.TypeInfo.IsReadOnly; public SequenceLengthSourceType LengthSourceType { get; set; } public SchemaIntegerType ImmediateLengthType { get; set; } diff --git a/Schema/src/binary/parser/MemberReferenceUtil.cs b/Schema/src/binary/parser/MemberReferenceUtil.cs index cf7967e..f980219 100644 --- a/Schema/src/binary/parser/MemberReferenceUtil.cs +++ b/Schema/src/binary/parser/MemberReferenceUtil.cs @@ -42,14 +42,11 @@ public static IMemberType WrapTypeInfoWithMemberType(ITypeInfo typeInfo) { case ISequenceTypeInfo sequenceTypeInfo: { return new BinarySchemaStructureParser.SequenceMemberType { SequenceTypeInfo = sequenceTypeInfo, - SequenceType = sequenceTypeInfo.IsArray - ? SequenceType.ARRAY - : SequenceType.LIST, ElementType = WrapTypeInfoWithMemberType(sequenceTypeInfo.ElementTypeInfo), LengthSourceType = sequenceTypeInfo.IsLengthConst - ? SequenceLengthSourceType.READONLY + ? SequenceLengthSourceType.READ_ONLY : ((ISequenceLengthSourceAttribute?) SymbolTypeUtil .GetAttribute( null, diff --git a/Schema/src/binary/parser/TypeInfo.cs b/Schema/src/binary/parser/TypeInfo.cs index a48c387..305bc9e 100644 --- a/Schema/src/binary/parser/TypeInfo.cs +++ b/Schema/src/binary/parser/TypeInfo.cs @@ -23,7 +23,7 @@ public enum SchemaTypeKind { public interface ITypeInfo { ITypeSymbol TypeSymbol { get; } SchemaTypeKind Kind { get; } - bool IsReadonly { get; } + bool IsReadOnly { get; } bool IsNullable { get; } } @@ -58,9 +58,11 @@ public interface IGenericTypeInfo : ITypeInfo { } public interface ISequenceTypeInfo : ITypeInfo { - bool IsArray { get; } + SequenceType SequenceType { get; } bool IsLengthConst { get; } ITypeInfo ElementTypeInfo { get; } + + string LengthName { get; } } public class TypeInfoParser { @@ -76,7 +78,8 @@ public enum ParseStatus { structureSymbol)) { // Tries to parse the type to get info about it var parseStatus = this.ParseMember( - memberSymbol, out var memberTypeInfo); + memberSymbol, + out var memberTypeInfo); yield return (parseStatus, memberSymbol, memberTypeInfo); } } @@ -192,7 +195,7 @@ public ParseStatus ParseTypeSymbol( typeSymbol, isReadonly, isNullable, - true, + SequenceType.MUTABLE_ARRAY, isReadonly, containedTypeInfo); return ParseStatus.SUCCESS; @@ -216,13 +219,13 @@ public ParseStatus ParseTypeSymbol( typeSymbol, isReadonly, isNullable, - false, + SequenceType.MUTABLE_LIST, false, containedTypeInfo); return ParseStatus.SUCCESS; } - if (SymbolTypeUtil.MatchesGeneric(namedTypeSymbol, + if (SymbolTypeUtil.MatchesGeneric(namedTypeSymbol, typeof(IReadOnlyList<>))) { var listTypeSymbol = typeSymbol as INamedTypeSymbol; @@ -240,7 +243,7 @@ public ParseStatus ParseTypeSymbol( typeSymbol, isReadonly, isNullable, - false, + SequenceType.READ_ONLY_LIST, isReadonly, containedTypeInfo); return ParseStatus.SUCCESS; @@ -259,7 +262,9 @@ public ParseStatus ParseTypeSymbol( .ConstraintTypes .Select(constraintType => { var parseStatus = this.ParseTypeSymbol( - constraintType, isReadonly, out var constraintTypeInfo); + constraintType, + isReadonly, + out var constraintTypeInfo); Asserts.Equal(ParseStatus.SUCCESS, parseStatus); return constraintTypeInfo; }) @@ -284,6 +289,7 @@ public ITypeInfo AssertParseTypeSymbol( if (parseStatus != ParseStatus.SUCCESS) { throw new NotImplementedException(); } + return typeInfo; } @@ -330,7 +336,7 @@ public BoolTypeInfo( bool isReadonly, bool isNullable) { this.TypeSymbol = typeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -339,7 +345,7 @@ public BoolTypeInfo( public SchemaPrimitiveType PrimitiveType => SchemaPrimitiveType.BOOLEAN; public SchemaTypeKind Kind => SchemaTypeKind.BOOL; - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -354,7 +360,7 @@ public FloatTypeInfo( this.TypeSymbol = typeSymbol; this.Kind = kind; this.NumberType = numberType; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -365,7 +371,7 @@ public FloatTypeInfo( public SchemaPrimitiveType PrimitiveType => SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive(this.NumberType); - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -379,7 +385,7 @@ public IntegerTypeInfo( this.TypeSymbol = typeSymbol; this.Kind = kind; this.IntegerType = integerType; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -393,7 +399,7 @@ public SchemaNumberType NumberType public SchemaPrimitiveType PrimitiveType => SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive(this.NumberType); - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -403,7 +409,7 @@ public CharTypeInfo( bool isReadonly, bool isNullable) { this.TypeSymbol = typeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -412,7 +418,7 @@ public CharTypeInfo( public ITypeSymbol TypeSymbol { get; } - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -422,7 +428,7 @@ public StringTypeInfo( bool isReadonly, bool isNullable) { this.TypeSymbol = typeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -430,7 +436,7 @@ public StringTypeInfo( public ITypeSymbol TypeSymbol { get; } - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -440,7 +446,7 @@ public EnumTypeInfo( bool isReadonly, bool isNullable) { this.TypeSymbol = typeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -449,7 +455,7 @@ public EnumTypeInfo( public ITypeSymbol TypeSymbol { get; } - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -459,7 +465,7 @@ public StructureTypeInfo( bool isReadonly, bool isNullable) { this.NamedTypeSymbol = namedTypeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -468,7 +474,7 @@ public StructureTypeInfo( public INamedTypeSymbol NamedTypeSymbol { get; } public ITypeSymbol TypeSymbol => this.NamedTypeSymbol; - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } public bool IsStruct => this.NamedTypeSymbol.TypeKind == TypeKind.Struct; @@ -482,7 +488,7 @@ public GenericTypeInfo( bool isNullable) { this.ConstraintTypeInfos = constraintTypeInfos; this.TypeParameterSymbol = typeParameterSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; } @@ -492,7 +498,7 @@ public GenericTypeInfo( public ITypeParameterSymbol TypeParameterSymbol { get; } public ITypeSymbol TypeSymbol => this.TypeParameterSymbol; - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } } @@ -501,13 +507,13 @@ public SequenceTypeInfo( ITypeSymbol typeSymbol, bool isReadonly, bool isNullable, - bool isArray, + SequenceType sequenceType, bool isLengthConst, ITypeInfo containedType) { this.TypeSymbol = typeSymbol; - this.IsReadonly = isReadonly; + this.IsReadOnly = isReadonly; this.IsNullable = isNullable; - this.IsArray = isArray; + this.SequenceType = sequenceType; this.IsLengthConst = isLengthConst; this.ElementTypeInfo = containedType; } @@ -516,12 +522,18 @@ public SequenceTypeInfo( public ITypeSymbol TypeSymbol { get; } - public bool IsReadonly { get; } + public bool IsReadOnly { get; } public bool IsNullable { get; } - public bool IsArray { get; } + public SequenceType SequenceType { get; } public bool IsLengthConst { get; } public ITypeInfo ElementTypeInfo { get; } + + public string LengthName + => this.SequenceType is SequenceType.MUTABLE_ARRAY + or SequenceType.IMMUTABLE_ARRAY + ? "Length" + : "Count"; } } } \ No newline at end of file diff --git a/Schema/src/binary/text/BinarySchemaReaderGenerator.cs b/Schema/src/binary/text/BinarySchemaReaderGenerator.cs index 2c1db13..28e6273 100644 --- a/Schema/src/binary/text/BinarySchemaReaderGenerator.cs +++ b/Schema/src/binary/text/BinarySchemaReaderGenerator.cs @@ -76,7 +76,7 @@ private static void ReadMember_( ITypeSymbol sourceSymbol, ISchemaMember member) { if (member.IsPosition) { - if (member.MemberType.IsReadonly) { + if (member.MemberType.IsReadOnly) { cbsb.WriteLine($"er.AssertPosition(this.{member.Name});"); } else { cbsb.WriteLine($"this.{member.Name} = er.Position;"); @@ -124,10 +124,11 @@ private static void ReadMember_( if (member.MemberType is not IPrimitiveMemberType && member.MemberType is not ISequenceMemberType { - SequenceType: SequenceType.ARRAY + SequenceTypeInfo.SequenceType: SequenceType + .MUTABLE_ARRAY }) { cbsb.WriteLine( - $"this.{member.Name} = new {SymbolTypeUtil.GetQualifiedNameFromCurrentSymbol(sourceSymbol, member.MemberType.TypeSymbol)}();"); + $"this.{member.Name} = new {sourceSymbol.GetQualifiedNameFromCurrentSymbol(member.MemberType.TypeSymbol)}();"); } } @@ -240,7 +241,7 @@ private static void ReadPrimitive_( primitiveType .AltFormat)); - if (!primitiveType.IsReadonly) { + if (!primitiveType.IsReadOnly) { var castText = ""; if (needToCast) { var castType = @@ -288,7 +289,7 @@ member.MemberType as .ConvertNumberToPrimitive( primitiveType.AltFormat)); - if (!primitiveType.IsReadonly) { + if (!primitiveType.IsReadOnly) { cbsb.WriteLine( $"this.{member.Name} = er.Read{readType}() != 0;"); } else { @@ -308,7 +309,7 @@ private static void ReadString_( Asserts.CastNonnull( member.MemberType as IStringType); - if (stringType.IsReadonly) { + if (stringType.IsReadOnly) { if (stringType.LengthSourceType == StringLengthSourceType.NULL_TERMINATED) { cbsb.WriteLine( @@ -365,23 +366,19 @@ private static void ReadStructure_( } HandleMemberEndianness_( - cbsb, - member, - () => - { - if (!structureMemberType.IsStruct) - { - cbsb.WriteLine($"this.{memberName}.Read(er);"); - } - else - { - cbsb.EnterBlock() - .WriteLine($"var value = this.{memberName};") - .WriteLine("value.Read(er);") - .WriteLine($"this.{memberName} = value;") - .ExitBlock(); - } - }); + cbsb, + member, + () => { + if (!structureMemberType.IsStruct) { + cbsb.WriteLine($"this.{memberName}.Read(er);"); + } else { + cbsb.EnterBlock() + .WriteLine($"var value = this.{memberName};") + .WriteLine("value.Read(er);") + .WriteLine($"this.{memberName} = value;") + .ExitBlock(); + } + }); } private static void ReadGeneric_( @@ -411,6 +408,7 @@ private static void ReadArray_( ISchemaMember member) { var arrayType = Asserts.CastNonnull(member.MemberType as ISequenceMemberType); + var sequenceType = arrayType.SequenceTypeInfo.SequenceType; if (arrayType.LengthSourceType == SequenceLengthSourceType.UNTIL_END_OF_STREAM) { var qualifiedElementName = @@ -420,7 +418,7 @@ private static void ReadArray_( var memberAccessor = $"this.{member.Name}"; - var isArray = arrayType.SequenceType == SequenceType.ARRAY; + var isArray = sequenceType == SequenceType.MUTABLE_ARRAY; { if (isArray && arrayType.ElementType is IPrimitiveMemberType @@ -527,7 +525,7 @@ arrayType.ElementType is IPrimitiveMemberType return; } else if (arrayType.LengthSourceType != - SequenceLengthSourceType.READONLY) { + SequenceLengthSourceType.READ_ONLY) { var isImmediate = arrayType.LengthSourceType == SequenceLengthSourceType.IMMEDIATE_VALUE; @@ -565,7 +563,7 @@ arrayType.ElementType is IStructureMemberType { }; // TODO: Handle readonly lists, can't be expanded like this! - if (arrayType.SequenceType == SequenceType.LIST) { + if (sequenceType == SequenceType.MUTABLE_LIST) { cbsb.EnterBlock($"while (this.{member.Name}.Count < {lengthName})"); if (hasReferenceElements) { cbsb.WriteLine( @@ -586,9 +584,9 @@ arrayType.ElementType is IStructureMemberType { if (hasReferenceElements) { cbsb.EnterBlock($"for (var i = 0; i < {lengthName}; ++i)") - .WriteLine( - $"this.{member.Name}[i] = new {qualifiedElementName}();") - .ExitBlock(); + .WriteLine( + $"this.{member.Name}[i] = new {qualifiedElementName}();") + .ExitBlock(); } } @@ -626,7 +624,7 @@ member.MemberType as var label = SchemaGeneratorUtil.GetPrimitiveLabel( primitiveElementType.PrimitiveType); - if (!primitiveElementType.IsReadonly) { + if (!primitiveElementType.IsReadOnly) { cbsb.WriteLine( $"er.Read{label}s(this.{member.Name});"); } else { @@ -644,12 +642,9 @@ member.MemberType as .ConvertNumberToPrimitive( primitiveElementType .AltFormat)); - if (!primitiveElementType.IsReadonly) { + if (!primitiveElementType.IsReadOnly) { var arrayLengthName = - arrayType.SequenceType == - SequenceType.ARRAY - ? "Length" - : "Count"; + arrayType.SequenceTypeInfo.LengthName; var castType = primitiveElementType.PrimitiveType == SchemaPrimitiveType.ENUM @@ -683,7 +678,7 @@ member.MemberType as structureElementType) { if (!structureElementType.IsStruct) { cbsb.EnterBlock( - $"foreach (var e in this.{member.Name})"); + $"foreach (var e in this.{member.Name})"); if (structureElementType.IsChild) { cbsb.WriteLine("e.Parent = this;"); @@ -691,18 +686,13 @@ member.MemberType as cbsb.WriteLine("e.Read(er);"); cbsb.ExitBlock(); - } - else - { + } else { var arrayLengthName = - arrayType.SequenceType == - SequenceType.ARRAY - ? "Length" - : "Count"; + arrayType.SequenceTypeInfo.LengthName; cbsb.EnterBlock( - $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)"); + $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)"); cbsb.WriteLine( - $"var e = this.{member.Name}[i];"); + $"var e = this.{member.Name}[i];"); if (structureElementType.IsChild) { cbsb.WriteLine("e.Parent = this;"); @@ -710,10 +700,11 @@ member.MemberType as cbsb.WriteLine("e.Read(er);"); cbsb.WriteLine( - $"this.{member.Name}[i] = e;"); + $"this.{member.Name}[i] = e;"); cbsb.ExitBlock(); } + return; } diff --git a/Schema/src/binary/text/BinarySchemaWriterGenerator.cs b/Schema/src/binary/text/BinarySchemaWriterGenerator.cs index d506a6c..15471e2 100644 --- a/Schema/src/binary/text/BinarySchemaWriterGenerator.cs +++ b/Schema/src/binary/text/BinarySchemaWriterGenerator.cs @@ -30,6 +30,7 @@ public string Generate(IBinarySchemaStructure structure) { foreach (var declaringType in declaringTypes) { cbsb.EnterBlock(SymbolTypeUtil.GetQualifiersAndNameFor(declaringType)); } + cbsb.EnterBlock(SymbolTypeUtil.GetQualifiersAndNameFor(typeSymbol)); cbsb.EnterBlock("public void Write(ISubEndianBinaryWriter ew)"); @@ -187,134 +188,199 @@ private static void WritePrimitive_( return; } - HandleMemberEndiannessAndTracking_(cbsb, member, () => { - var readType = SchemaGeneratorUtil.GetPrimitiveLabel( - primitiveType.UseAltFormat - ? SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( - primitiveType.AltFormat) - : primitiveType.PrimitiveType); - - var isNotDelayed = !primitiveType.SizeOfStream && - primitiveType.AccessChainToSizeOf == null - && primitiveType.AccessChainToPointer == null; - if (isNotDelayed) { - var needToCast = - primitiveType.UseAltFormat && - primitiveType.PrimitiveType != - SchemaPrimitiveTypesUtil.GetUnderlyingPrimitiveType( - SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( - primitiveType.AltFormat)); - - var castText = ""; - if (needToCast) { - var castType = - SchemaGeneratorUtil.GetTypeName(primitiveType.AltFormat); - castText = $"({castType}) "; - } - - var accessText = $"this.{member.Name}"; - if (member.MemberType.TypeInfo.IsNullable) { - accessText = $"{accessText}.Value"; - } - - cbsb.WriteLine( - $"ew.Write{readType}({castText}{accessText});"); - } else { - var needToCast = - primitiveType.PrimitiveType != SchemaPrimitiveType.INT64; - - var castText = ""; - if (needToCast) { - var castType = - SchemaGeneratorUtil.GetTypeName( - SchemaPrimitiveTypesUtil.ConvertPrimitiveToNumber( - primitiveType.PrimitiveType)); - castText = $".ContinueWith(task => ({castType}) task.Result)"; - } - - string accessText; - var typeChain = primitiveType.AccessChainToSizeOf ?? - primitiveType.AccessChainToPointer; - if (typeChain != null) { - accessText = - primitiveType.AccessChainToSizeOf != null - ? $"ew.GetSizeOfMemberRelativeToScope(\"{typeChain.Path}\")" - : $"ew.GetPointerToMemberRelativeToScope(\"{typeChain.Path}\")"; - } else { - accessText = "ew.GetAbsoluteLength()"; - } - cbsb.WriteLine( - $"ew.Write{readType}Delayed({accessText}{castText});"); - } - }); + HandleMemberEndiannessAndTracking_(cbsb, + member, + () => { + var readType = SchemaGeneratorUtil + .GetPrimitiveLabel( + primitiveType.UseAltFormat + ? SchemaPrimitiveTypesUtil + .ConvertNumberToPrimitive( + primitiveType + .AltFormat) + : primitiveType + .PrimitiveType); + + var isNotDelayed = + !primitiveType.SizeOfStream && + primitiveType + .AccessChainToSizeOf == null + && primitiveType + .AccessChainToPointer == + null; + if (isNotDelayed) { + var needToCast = + primitiveType.UseAltFormat && + primitiveType.PrimitiveType != + SchemaPrimitiveTypesUtil + .GetUnderlyingPrimitiveType( + SchemaPrimitiveTypesUtil + .ConvertNumberToPrimitive( + primitiveType + .AltFormat)); + + var castText = ""; + if (needToCast) { + var castType = + SchemaGeneratorUtil + .GetTypeName( + primitiveType + .AltFormat); + castText = $"({castType}) "; + } + + var accessText = + $"this.{member.Name}"; + if (member.MemberType.TypeInfo + .IsNullable) { + accessText = + $"{accessText}.Value"; + } + + cbsb.WriteLine( + $"ew.Write{readType}({castText}{accessText});"); + } else { + var needToCast = + primitiveType.PrimitiveType != + SchemaPrimitiveType.INT64; + + var castText = ""; + if (needToCast) { + var castType = + SchemaGeneratorUtil + .GetTypeName( + SchemaPrimitiveTypesUtil + .ConvertPrimitiveToNumber( + primitiveType + .PrimitiveType)); + castText = + $".ContinueWith(task => ({castType}) task.Result)"; + } + + string accessText; + var typeChain = + primitiveType + .AccessChainToSizeOf ?? + primitiveType + .AccessChainToPointer; + if (typeChain != null) { + accessText = + primitiveType + .AccessChainToSizeOf != + null + ? $"ew.GetSizeOfMemberRelativeToScope(\"{typeChain.Path}\")" + : $"ew.GetPointerToMemberRelativeToScope(\"{typeChain.Path}\")"; + } else { + accessText = + "ew.GetAbsoluteLength()"; + } + + cbsb.WriteLine( + $"ew.Write{readType}Delayed({accessText}{castText});"); + } + }); } private static void WriteBoolean_( ICurlyBracketTextWriter cbsb, ISchemaMember member) { - HandleMemberEndiannessAndTracking_(cbsb, member, () => { - var primitiveType = - Asserts.CastNonnull(member.MemberType as IPrimitiveMemberType); - - var writeType = SchemaGeneratorUtil.GetPrimitiveLabel( - SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( - primitiveType.AltFormat)); - var castType = SchemaGeneratorUtil.GetTypeName( - primitiveType.AltFormat); - - var accessText = $"this.{member.Name}"; - if (member.MemberType.TypeInfo.IsNullable) { - accessText = $"{accessText}.Value"; - } - - cbsb.WriteLine( - $"ew.Write{writeType}(({castType}) ({accessText} ? 1 : 0));"); - }); + HandleMemberEndiannessAndTracking_(cbsb, + member, + () => { + var primitiveType = + Asserts.CastNonnull( + member.MemberType as + IPrimitiveMemberType); + + var writeType = SchemaGeneratorUtil + .GetPrimitiveLabel( + SchemaPrimitiveTypesUtil + .ConvertNumberToPrimitive( + primitiveType + .AltFormat)); + var castType = SchemaGeneratorUtil + .GetTypeName( + primitiveType.AltFormat); + + var accessText = + $"this.{member.Name}"; + if (member.MemberType.TypeInfo + .IsNullable) { + accessText = $"{accessText}.Value"; + } + + cbsb.WriteLine( + $"ew.Write{writeType}(({castType}) ({accessText} ? 1 : 0));"); + }); } private static void WriteString_( ICurlyBracketTextWriter cbsb, ISchemaMember member) { - HandleMemberEndiannessAndTracking_(cbsb, member, () => { - var stringType = Asserts.CastNonnull(member.MemberType as IStringType); - - if (stringType.LengthSourceType == - StringLengthSourceType.NULL_TERMINATED) { - cbsb.WriteLine($"ew.WriteStringNT(this.{member.Name});"); - } else if (stringType.LengthSourceType == - StringLengthSourceType.CONST) { - cbsb.WriteLine( - $"ew.WriteStringWithExactLength(this.{member.Name}, {stringType.ConstLength});"); - } else if (stringType.LengthSourceType == - StringLengthSourceType.IMMEDIATE_VALUE) { - var immediateLengthType = stringType.ImmediateLengthType; - - var needToCast = !immediateLengthType.CanAcceptAnInt(); - - var castText = ""; - if (needToCast) { - var castType = immediateLengthType.GetTypeName(); - castText = $"({castType}) "; - } - - var accessText = $"this.{member.Name}.Length"; - - var writeType = stringType.ImmediateLengthType.GetIntLabel(); - cbsb.WriteLine($"ew.Write{writeType}({castText}{accessText});") - .WriteLine($"ew.WriteString(this.{member.Name});"); - } else { - cbsb.WriteLine($"ew.WriteString(this.{member.Name});"); - } - }); + HandleMemberEndiannessAndTracking_(cbsb, + member, + () => { + var stringType = + Asserts.CastNonnull( + member.MemberType as + IStringType); + + if (stringType.LengthSourceType == + StringLengthSourceType + .NULL_TERMINATED) { + cbsb.WriteLine( + $"ew.WriteStringNT(this.{member.Name});"); + } else if (stringType + .LengthSourceType == + StringLengthSourceType.CONST) { + cbsb.WriteLine( + $"ew.WriteStringWithExactLength(this.{member.Name}, {stringType.ConstLength});"); + } else if (stringType + .LengthSourceType == + StringLengthSourceType + .IMMEDIATE_VALUE) { + var immediateLengthType = + stringType.ImmediateLengthType; + + var needToCast = + !immediateLengthType + .CanAcceptAnInt(); + + var castText = ""; + if (needToCast) { + var castType = + immediateLengthType + .GetTypeName(); + castText = $"({castType}) "; + } + + var accessText = + $"this.{member.Name}.Length"; + + var writeType = + stringType.ImmediateLengthType + .GetIntLabel(); + cbsb.WriteLine( + $"ew.Write{writeType}({castText}{accessText});") + .WriteLine( + $"ew.WriteString(this.{member.Name});"); + } else { + cbsb.WriteLine( + $"ew.WriteString(this.{member.Name});"); + } + }); } private static void WriteStructure_( ICurlyBracketTextWriter cbsb, ISchemaMember member) { - HandleMemberEndiannessAndTracking_(cbsb, member, () => { - // TODO: Do value types need to be handled differently? - cbsb.WriteLine($"this.{member.Name}.Write(ew);"); - }); + HandleMemberEndiannessAndTracking_(cbsb, + member, + () => { + // TODO: Do value types need to be handled differently? + cbsb.WriteLine( + $"this.{member.Name}.Write(ew);"); + }); } private static void WriteArray_( @@ -323,7 +389,7 @@ private static void WriteArray_( ISchemaMember member) { var arrayType = Asserts.CastNonnull(member.MemberType as ISequenceMemberType); - if (arrayType.LengthSourceType != SequenceLengthSourceType.READONLY) { + if (arrayType.LengthSourceType != SequenceLengthSourceType.READ_ONLY) { var isImmediate = arrayType.LengthSourceType == SequenceLengthSourceType.IMMEDIATE_VALUE; @@ -336,9 +402,7 @@ private static void WriteArray_( SchemaPrimitiveTypesUtil.ConvertIntToNumber( arrayType.ImmediateLengthType)); - var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY - ? "Length" - : "Count"; + var arrayLengthName = arrayType.SequenceTypeInfo.LengthName; var arrayLengthAccessor = $"this.{member.Name}.{arrayLengthName}"; cbsb.WriteLine( @@ -353,80 +417,107 @@ private static void WriteIntoArray_( ICurlyBracketTextWriter cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { - HandleMemberEndiannessAndTracking_(cbsb, member, () => { - var arrayType = - Asserts.CastNonnull(member.MemberType as ISequenceMemberType); - - var elementType = arrayType.ElementType; - if (elementType is IGenericMemberType genericElementType) { - elementType = genericElementType.ConstraintType; - } - - if (elementType is IPrimitiveMemberType primitiveElementType) { - // Primitives that don't need to be cast are the easiest to write. - if (!primitiveElementType.UseAltFormat) { - var label = - SchemaGeneratorUtil.GetPrimitiveLabel( - primitiveElementType.PrimitiveType); - cbsb.WriteLine($"ew.Write{label}s(this.{member.Name});"); - return; - } - - // Primitives that *do* need to be cast have to be written individually. - var writeType = SchemaGeneratorUtil.GetPrimitiveLabel( - SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( - primitiveElementType.AltFormat)); - var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY - ? "Length" - : "Count"; - var needToCast = primitiveElementType.UseAltFormat && - primitiveElementType.PrimitiveType != - SchemaPrimitiveTypesUtil.GetUnderlyingPrimitiveType( - SchemaPrimitiveTypesUtil - .ConvertNumberToPrimitive( - primitiveElementType.AltFormat)); - - var castText = ""; - if (needToCast) { - var castType = - SchemaGeneratorUtil.GetTypeName(primitiveElementType.AltFormat); - castText = $"({castType}) "; - } - - cbsb.EnterBlock( - $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") - .WriteLine( - $"ew.Write{writeType}({castText}this.{member.Name}[i]);") - .ExitBlock(); - return; - } - - if (elementType is IStructureMemberType structureElementType) { - //if (structureElementType.IsReferenceType) { - cbsb.EnterBlock($"foreach (var e in this.{member.Name})") - .WriteLine("e.Write(ew);") - .ExitBlock(); - // TODO: Do value types need to be read like below? - /*} - // Value types (mainly structs) have to be pulled out, read, then put - // back in. - else { - var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY - ? "Length" - : "Count"; - cbsb.EnterBlock( - $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") - .WriteLine($"var e = this.{member.Name}[i];") - .WriteLine("e.Read(ew);") - .WriteLine($"this.{member.Name}[i] = e;") - .ExitBlock(); - }*/ - return; - } - - // Anything that makes it down here probably isn't meant to be read. - throw new NotImplementedException(); - }); + HandleMemberEndiannessAndTracking_(cbsb, + member, + () => { + var arrayType = + Asserts.CastNonnull( + member.MemberType as + ISequenceMemberType); + + var elementType = + arrayType.ElementType; + if (elementType is IGenericMemberType + genericElementType) { + elementType = genericElementType + .ConstraintType; + } + + if (elementType is + IPrimitiveMemberType + primitiveElementType) { + // Primitives that don't need to be cast are the easiest to write. + if (!primitiveElementType + .UseAltFormat) { + var label = + SchemaGeneratorUtil + .GetPrimitiveLabel( + primitiveElementType + .PrimitiveType); + cbsb.WriteLine( + $"ew.Write{label}s(this.{member.Name});"); + return; + } + + // Primitives that *do* need to be cast have to be written individually. + var writeType = + SchemaGeneratorUtil + .GetPrimitiveLabel( + SchemaPrimitiveTypesUtil + .ConvertNumberToPrimitive( + primitiveElementType + .AltFormat)); + var arrayLengthName = + arrayType.SequenceTypeInfo.LengthName; + var needToCast = + primitiveElementType + .UseAltFormat && + primitiveElementType + .PrimitiveType != + SchemaPrimitiveTypesUtil + .GetUnderlyingPrimitiveType( + SchemaPrimitiveTypesUtil + .ConvertNumberToPrimitive( + primitiveElementType + .AltFormat)); + + var castText = ""; + if (needToCast) { + var castType = + SchemaGeneratorUtil + .GetTypeName( + primitiveElementType + .AltFormat); + castText = $"({castType}) "; + } + + cbsb.EnterBlock( + $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") + .WriteLine( + $"ew.Write{writeType}({castText}this.{member.Name}[i]);") + .ExitBlock(); + return; + } + + if (elementType is + IStructureMemberType + structureElementType) { + //if (structureElementType.IsReferenceType) { + cbsb.EnterBlock( + $"foreach (var e in this.{member.Name})") + .WriteLine("e.Write(ew);") + .ExitBlock(); + // TODO: Do value types need to be read like below? + /*} + // Value types (mainly structs) have to be pulled out, read, then put + // back in. + else { + var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY + ? "Length" + : "Count"; + cbsb.EnterBlock( + $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") + .WriteLine($"var e = this.{member.Name}[i];") + .WriteLine("e.Read(ew);") + .WriteLine($"this.{member.Name}[i] = e;") + .ExitBlock(); + }*/ + return; + } + + // Anything that makes it down here probably isn't meant to be read. + throw new NotImplementedException(); + }); } } } \ No newline at end of file diff --git a/Schema/src/util/sequences/ISequence.cs b/Schema/src/util/sequences/ISequence.cs index bc731e2..b89ce9b 100644 --- a/Schema/src/util/sequences/ISequence.cs +++ b/Schema/src/util/sequences/ISequence.cs @@ -2,14 +2,14 @@ namespace schema.util.sequences { public interface IReadOnlySequence : IEnumerable { - int Length { get; } + int Count { get; } T this[int index] { get; } IReadOnlySequence CloneWithNewLength(int newLength); } public interface ISequence : IReadOnlySequence { - new int Length { get; set; } + new int Count { get; set; } new T this[int index] { get; set; } void Clear(); } diff --git a/Schema/src/util/sequences/SequencesUtil.cs b/Schema/src/util/sequences/SequencesUtil.cs index 17f09fd..da11436 100644 --- a/Schema/src/util/sequences/SequencesUtil.cs +++ b/Schema/src/util/sequences/SequencesUtil.cs @@ -49,7 +49,7 @@ public static IReadOnlyList ResizeSequence(IReadOnlyList list, public static void ResizeSequenceInPlace(ISequence list, int length) { SequencesUtil.AssertLengthNonnegative_(length); - list.Length = length; + list.Count = length; } public static IReadOnlySequence ResizeSequence(