diff --git a/Schema/Schema.csproj b/Schema/Schema.csproj
index e99b772..d26b5ab 100644
--- a/Schema/Schema.csproj
+++ b/Schema/Schema.csproj
@@ -20,12 +20,9 @@
-
-
-
@@ -35,4 +32,22 @@
+
+
+
+
+
+
+
+ $(GetTargetPathDependsOn);GetDependencyTargetPaths
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Schema/src/binary/text/BinarySchemaReaderGenerator.cs b/Schema/src/binary/text/BinarySchemaReaderGenerator.cs
index 423d024..fb551af 100644
--- a/Schema/src/binary/text/BinarySchemaReaderGenerator.cs
+++ b/Schema/src/binary/text/BinarySchemaReaderGenerator.cs
@@ -10,7 +10,6 @@
using schema.util.asserts;
using schema.util.symbols;
using schema.util.text;
-using schema.util.types;
namespace schema.binary.text {
public class BinarySchemaReaderGenerator {
@@ -19,12 +18,8 @@ public class BinarySchemaReaderGenerator {
public string Generate(IBinarySchemaContainer container) {
var typeSymbol = container.TypeSymbol;
- var typeNamespace = typeSymbol.GetFullyQualifiedNamespace();
-
- var declaringTypes = typeSymbol.GetDeclaringTypesDownward();
-
var sb = new StringBuilder();
- using var cbsb = new CurlyBracketTextWriter(new StringWriter(sb));
+ using var sw = new SourceWriter(new StringWriter(sb));
{
var dependencies = new List { "System", "schema.binary" };
@@ -42,85 +37,71 @@ public string Generate(IBinarySchemaContainer container) {
dependencies.Sort(StringComparer.Ordinal);
foreach (var dependency in dependencies) {
- cbsb.WriteLine($"using {dependency};");
+ sw.WriteLine($"using {dependency};");
}
- cbsb.WriteLine("");
- }
-
- // TODO: Handle fancier cases here
- if (typeNamespace != null) {
- cbsb.EnterBlock($"namespace {typeNamespace}");
- }
-
- foreach (var declaringType in declaringTypes) {
- cbsb.EnterBlock(declaringType.GetQualifiersAndNameAndGenericParametersFor());
+ sw.WriteLine("");
}
- cbsb.EnterBlock(typeSymbol.GetQualifiersAndNameAndGenericParametersFor());
-
- cbsb.EnterBlock($"public void Read(IBinaryReader {READER})");
- {
- var hasLocalPositions = container.LocalPositions;
- if (hasLocalPositions) {
- cbsb.WriteLine($"{READER}.PushLocalSpace();");
- }
-
- var hasEndianness = container.Endianness != null;
- if (hasEndianness) {
- cbsb.WriteLine(
- $"{READER}.PushContainerEndianness({SchemaGeneratorUtil.GetEndiannessName(container.Endianness.Value)});");
- }
-
- foreach (var member in container.Members) {
- if (member is ISchemaValueMember valueMember) {
- BinarySchemaReaderGenerator.ReadValueMember_(
- cbsb,
- typeSymbol,
- valueMember);
- } else if (member is ISchemaMethodMember) {
- cbsb.WriteLine($"this.{member.Name}({READER});");
- }
- }
+ sw.WriteNamespaceAndParentTypeBlocks(
+ typeSymbol,
+ () => {
+ sw.EnterBlock(
+ typeSymbol.GetQualifiersAndNameAndGenericParametersFor());
+
+ sw.EnterBlock($"public void Read(IBinaryReader {READER})");
+ {
+ var hasLocalPositions = container.LocalPositions;
+ if (hasLocalPositions) {
+ sw.WriteLine($"{READER}.PushLocalSpace();");
+ }
- if (hasEndianness) {
- cbsb.WriteLine($"{READER}.PopEndianness();");
- }
+ var hasEndianness = container.Endianness != null;
+ if (hasEndianness) {
+ sw.WriteLine(
+ $"{READER}.PushContainerEndianness({SchemaGeneratorUtil.GetEndiannessName(container.Endianness.Value)});");
+ }
- if (hasLocalPositions) {
- cbsb.WriteLine($"{READER}.PopLocalSpace();");
- }
- }
- cbsb.ExitBlock();
+ foreach (var member in container.Members) {
+ if (member is ISchemaValueMember valueMember) {
+ BinarySchemaReaderGenerator.ReadValueMember_(
+ sw,
+ typeSymbol,
+ valueMember);
+ } else if (member is ISchemaMethodMember) {
+ sw.WriteLine($"this.{member.Name}({READER});");
+ }
+ }
- // TODO: Handle fancier cases here
+ if (hasEndianness) {
+ sw.WriteLine($"{READER}.PopEndianness();");
+ }
- // type
- cbsb.ExitBlock();
+ if (hasLocalPositions) {
+ sw.WriteLine($"{READER}.PopLocalSpace();");
+ }
+ }
+ sw.ExitBlock();
- // parent types
- foreach (var declaringType in declaringTypes) {
- cbsb.ExitBlock();
- }
+ // TODO: Handle fancier cases here
- // namespace
- if (typeNamespace != null) {
- cbsb.ExitBlock();
- }
+ // type
+ sw.ExitBlock();
+ });
var generatedCode = sb.ToString();
return generatedCode;
}
private static void ReadValueMember_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
ISchemaValueMember member) {
if (member.IsPosition) {
if (member.MemberType.IsReadOnly) {
- cbsb.WriteLine($"{READER}.AssertPosition(this.{member.Name});");
+ sw.WriteLine($"{READER}.AssertPosition(this.{member.Name});");
} else {
- cbsb.WriteLine($"this.{member.Name} = {READER}.Position;");
+ sw.WriteLine($"this.{member.Name} = {READER}.Position;");
}
return;
@@ -137,14 +118,14 @@ private static void ReadValueMember_(
var nullValue = offset.NullValue;
var readBlockPrefix = "";
if (nullValue != null) {
- cbsb.EnterBlock($"if (this.{offset.OffsetName.Name} == {nullValue})")
+ sw.EnterBlock($"if (this.{offset.OffsetName.Name} == {nullValue})")
.WriteLine($"this.{member.Name} = null;")
.ExitBlock();
readBlockPrefix = "else";
}
- cbsb.EnterBlock(readBlockPrefix)
+ sw.EnterBlock(readBlockPrefix)
.WriteLine($"var tempLocation = {READER}.Position;")
.WriteLine(
$"{READER}.Position = this.{offset.OffsetName.Name};");
@@ -154,7 +135,7 @@ private static void ReadValueMember_(
var immediateIfBoolean =
ifBoolean?.SourceType == IfBooleanSourceType.IMMEDIATE_VALUE;
if (immediateIfBoolean) {
- cbsb.EnterBlock();
+ sw.EnterBlock();
}
if (ifBoolean != null) {
@@ -163,20 +144,20 @@ private static void ReadValueMember_(
var booleanPrimitiveType = booleanNumberType.AsPrimitiveType();
var booleanPrimitiveLabel =
SchemaGeneratorUtil.GetPrimitiveLabel(booleanPrimitiveType);
- cbsb.WriteLine(
+ sw.WriteLine(
$"var b = {READER}.Read{booleanPrimitiveLabel}() != 0;")
.EnterBlock("if (b)");
} else {
- cbsb.EnterBlock($"if (this.{ifBoolean.OtherMember.Name})");
+ sw.EnterBlock($"if (this.{ifBoolean.OtherMember.Name})");
}
if (member.MemberType is not IPrimitiveMemberType &&
member.MemberType is not IContainerMemberType &&
member.MemberType is not ISequenceMemberType {
- SequenceTypeInfo.SequenceType: SequenceType
+ SequenceTypeInfo.SequenceType: SequenceType
.MUTABLE_ARRAY
}) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = new {sourceSymbol.GetQualifiedNameFromCurrentSymbol(member.MemberType.TypeSymbol)}();");
}
}
@@ -188,51 +169,51 @@ member.MemberType is not ISequenceMemberType {
switch (memberType) {
case IPrimitiveMemberType: {
- BinarySchemaReaderGenerator.ReadPrimitive_(
- cbsb,
- sourceSymbol,
- member);
- break;
- }
- case IStringType: {
- BinarySchemaReaderGenerator.ReadString_(cbsb, member);
- break;
- }
- case IContainerMemberType containerMemberType: {
- BinarySchemaReaderGenerator.ReadContainer_(cbsb,
+ BinarySchemaReaderGenerator.ReadPrimitive_(
+ sw,
sourceSymbol,
- containerMemberType,
member);
- break;
- }
+ break;
+ }
+ case IStringType: {
+ BinarySchemaReaderGenerator.ReadString_(sw, member);
+ break;
+ }
+ case IContainerMemberType containerMemberType: {
+ BinarySchemaReaderGenerator.ReadContainer_(sw,
+ sourceSymbol,
+ containerMemberType,
+ member);
+ break;
+ }
case ISequenceMemberType: {
- BinarySchemaReaderGenerator.ReadArray_(cbsb, sourceSymbol, member);
- break;
- }
+ BinarySchemaReaderGenerator.ReadArray_(sw, sourceSymbol, member);
+ break;
+ }
default: {
- // Anything that makes it down here probably isn't meant to be read.
- throw new NotImplementedException();
- }
+ // Anything that makes it down here probably isn't meant to be read.
+ throw new NotImplementedException();
+ }
}
if (ifBoolean != null) {
- cbsb.ExitBlock()
+ sw.ExitBlock()
.EnterBlock("else")
.WriteLine($"this.{member.Name} = null;")
.ExitBlock();
if (immediateIfBoolean) {
- cbsb.ExitBlock();
+ sw.ExitBlock();
}
}
if (offset != null) {
- cbsb.WriteLine($"{READER}.Position = tempLocation;")
+ sw.WriteLine($"{READER}.Position = tempLocation;")
.ExitBlock();
}
}
private static void Align_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
var align = member.Align;
if (align == null) {
@@ -240,47 +221,47 @@ private static void Align_(
}
var valueName = align.Method switch {
- AlignSourceType.CONST => $"{align.ConstAlign}",
- AlignSourceType.OTHER_MEMBER => $"{align.OtherMember.Name}"
+ AlignSourceType.CONST => $"{align.ConstAlign}",
+ AlignSourceType.OTHER_MEMBER => $"{align.OtherMember.Name}"
};
- cbsb.WriteLine($"{READER}.Align({valueName});");
+ sw.WriteLine($"{READER}.Align({valueName});");
}
private static void HandleMemberEndianness_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member,
Action handler) {
var hasEndianness = member.Endianness != null;
if (hasEndianness) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{READER}.PushMemberEndianness({SchemaGeneratorUtil.GetEndiannessName(member.Endianness.Value)});");
}
- BinarySchemaReaderGenerator.Align_(cbsb, member);
+ BinarySchemaReaderGenerator.Align_(sw, member);
handler();
if (hasEndianness) {
- cbsb.WriteLine($"{READER}.PopEndianness();");
+ sw.WriteLine($"{READER}.PopEndianness();");
}
}
private static void ReadPrimitive_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
ISchemaValueMember member) {
var primitiveType =
Asserts.CastNonnull(member.MemberType as IPrimitiveMemberType);
HandleMemberEndianness_(
- cbsb,
+ sw,
member,
() => {
if (!primitiveType.IsReadOnly) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = {GetReadPrimitiveText_(sourceSymbol, primitiveType)};");
} else {
- cbsb.WriteLine($"{GetAssertPrimitiveText_(
+ sw.WriteLine($"{GetAssertPrimitiveText_(
primitiveType,
$"this.{member.Name}")};");
}
@@ -288,10 +269,10 @@ private static void ReadPrimitive_(
}
private static void ReadString_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
HandleMemberEndianness_(
- cbsb,
+ sw,
member,
() => {
var stringType =
@@ -301,10 +282,10 @@ private static void ReadString_(
var encodingType = "";
if (stringType.EncodingType != StringEncodingType.ASCII) {
encodingType = stringType.EncodingType switch {
- StringEncodingType.UTF8 => "StringEncodingType.UTF8",
- StringEncodingType.UTF16 => "StringEncodingType.UTF16",
- StringEncodingType.UTF32 => "StringEncodingType.UTF32",
- _ => throw new ArgumentOutOfRangeException()
+ StringEncodingType.UTF8 => "StringEncodingType.UTF8",
+ StringEncodingType.UTF16 => "StringEncodingType.UTF16",
+ StringEncodingType.UTF32 => "StringEncodingType.UTF32",
+ _ => throw new ArgumentOutOfRangeException()
};
}
@@ -314,10 +295,10 @@ private static void ReadString_(
if (stringType.IsReadOnly) {
if (stringType.LengthSourceType ==
StringLengthSourceType.NULL_TERMINATED) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{READER}.AssertStringNT({encodingTypeWithComma}this.{member.Name});");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{READER}.AssertString({encodingTypeWithComma}this.{member.Name});");
}
@@ -326,7 +307,7 @@ private static void ReadString_(
if (stringType.LengthSourceType ==
StringLengthSourceType.NULL_TERMINATED) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = {READER}.ReadStringNT({encodingType});");
return;
}
@@ -336,7 +317,7 @@ private static void ReadString_(
: "ReadString";
if (stringType.LengthSourceType == StringLengthSourceType.CONST) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = {READER}.{readMethod}({encodingTypeWithComma}{stringType.ConstLength});");
return;
}
@@ -346,7 +327,7 @@ private static void ReadString_(
var readType =
SchemaGeneratorUtil.GetIntLabel(
stringType.ImmediateLengthType);
- cbsb.EnterBlock()
+ sw.EnterBlock()
.WriteLine($"var l = {READER}.Read{readType}();")
.WriteLine(
$"this.{member.Name} = {READER}.{readMethod}({encodingTypeWithComma}l);")
@@ -356,7 +337,7 @@ private static void ReadString_(
if (stringType.LengthSourceType ==
StringLengthSourceType.OTHER_MEMBER) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = {READER}.{readMethod}({encodingTypeWithComma}{stringType.LengthMember.Name});");
return;
}
@@ -367,18 +348,18 @@ private static void ReadString_(
}
private static void ReadContainer_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
IContainerMemberType containerMemberType,
ISchemaValueMember member) {
// TODO: Do value types need to be handled differently?
var memberName = member.Name;
if (containerMemberType.IsChild) {
- cbsb.WriteLine($"this.{memberName}.Parent = this;");
+ sw.WriteLine($"this.{memberName}.Parent = this;");
}
HandleMemberEndianness_(
- cbsb,
+ sw,
member,
() => {
var isNullable = containerMemberType.TypeInfo.IsNullable;
@@ -390,13 +371,13 @@ private static void ReadContainer_(
containerMemberType.TypeSymbol);
if (isNullable) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{memberName} = {READER}.ReadNew<{qualifiedTypeName}>();");
} else {
if (!isStruct) {
- cbsb.WriteLine($"this.{memberName}.Read({READER});");
+ sw.WriteLine($"this.{memberName}.Read({READER});");
} else {
- cbsb.EnterBlock()
+ sw.EnterBlock()
.WriteLine($"var value = this.{memberName};")
.WriteLine($"value.Read({READER});")
.WriteLine($"this.{memberName} = value;")
@@ -407,7 +388,7 @@ private static void ReadContainer_(
}
private static void ReadArray_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
ISchemaValueMember member) {
var arrayType =
@@ -441,10 +422,10 @@ arrayType.ElementType is IPrimitiveMemberType
var label =
SchemaGeneratorUtil.GetPrimitiveLabel(
primitiveElementType.PrimitiveType);
- cbsb.WriteLine(
+ sw.WriteLine(
$"{memberAccessor} = {READER}.Read{label}s({readCountAccessor});");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{memberAccessor} = new {qualifiedElementName}[{readCountAccessor}];")
.EnterBlock(
$"for (var i = 0; i < {memberAccessor}.Length; ++i)")
@@ -457,20 +438,20 @@ arrayType.ElementType is IPrimitiveMemberType
}
}
- cbsb.EnterBlock();
+ sw.EnterBlock();
if (!isArray) {
- cbsb.WriteLine($"{memberAccessor}.Clear();");
+ sw.WriteLine($"{memberAccessor}.Clear();");
}
var target = isArray ? "temp" : $"this.{member.Name}";
if (isArray) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"var {target} = new List<{qualifiedElementName}>();");
}
{
- cbsb.EnterBlock($"while (!{READER}.Eof)");
+ sw.EnterBlock($"while (!{READER}.Eof)");
{
var elementType = arrayType.ElementType;
if (elementType is IGenericMemberType genericElementType) {
@@ -478,28 +459,28 @@ arrayType.ElementType is IPrimitiveMemberType
}
if (elementType is IPrimitiveMemberType primitiveElementType) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{target}.Add({GetReadPrimitiveText_(sourceSymbol, primitiveElementType)});");
} else if
(elementType is IContainerMemberType containerElementType) {
- cbsb.WriteLine($"var e = new {qualifiedElementName}();");
+ sw.WriteLine($"var e = new {qualifiedElementName}();");
if (containerElementType.IsChild) {
- cbsb.WriteLine("e.Parent = this;");
+ sw.WriteLine("e.Parent = this;");
}
- cbsb.WriteLine($"e.Read({READER});");
- cbsb.WriteLine($"{target}.Add(e);");
+ sw.WriteLine($"e.Read({READER});");
+ sw.WriteLine($"{target}.Add(e);");
}
}
- cbsb.ExitBlock();
+ sw.ExitBlock();
}
if (isArray) {
- cbsb.WriteLine($"this.{member.Name} = {target}.ToArray();");
+ sw.WriteLine($"this.{member.Name} = {target}.ToArray();");
}
- cbsb.ExitBlock();
+ sw.ExitBlock();
return;
} else if (arrayType.LengthSourceType !=
@@ -509,11 +490,11 @@ arrayType.ElementType is IPrimitiveMemberType
SequenceLengthSourceType.IMMEDIATE_VALUE;
var lengthName = arrayType.LengthSourceType switch {
- SequenceLengthSourceType.IMMEDIATE_VALUE => "c",
- SequenceLengthSourceType.OTHER_MEMBER =>
- $"this.{arrayType.LengthMember!.Name}",
- SequenceLengthSourceType.CONST_LENGTH =>
- $"{arrayType.ConstLength}",
+ SequenceLengthSourceType.IMMEDIATE_VALUE => "c",
+ SequenceLengthSourceType.OTHER_MEMBER =>
+ $"this.{arrayType.LengthMember!.Name}",
+ SequenceLengthSourceType.CONST_LENGTH =>
+ $"{arrayType.ConstLength}",
};
var castText = "";
@@ -530,39 +511,39 @@ arrayType.ElementType is IPrimitiveMemberType
if (isImmediate) {
var readType = SchemaGeneratorUtil.GetIntLabel(
arrayType.ImmediateLengthType);
- cbsb.EnterBlock()
+ sw.EnterBlock()
.WriteLine($"var {lengthName} = {READER}.Read{readType}();");
}
var inPlace =
arrayType.SequenceTypeInfo.SequenceType ==
- SequenceType.MUTABLE_LIST
- || arrayType.SequenceTypeInfo is {
- SequenceType: SequenceType.MUTABLE_SEQUENCE,
- IsLengthConst: false
+ SequenceType.MUTABLE_LIST ||
+ arrayType.SequenceTypeInfo is {
+ SequenceType: SequenceType.MUTABLE_SEQUENCE,
+ IsLengthConst: false
};
if (inPlace) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"SequencesUtil.ResizeSequenceInPlace(this.{member.Name}, {castText}{lengthName});");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"this.{member.Name} = SequencesUtil.CloneAndResizeSequence(this.{member.Name}, {castText}{lengthName});");
}
if (isImmediate) {
- cbsb.ExitBlock();
+ sw.ExitBlock();
}
}
- BinarySchemaReaderGenerator.ReadIntoArray_(cbsb, sourceSymbol, member);
+ BinarySchemaReaderGenerator.ReadIntoArray_(sw, sourceSymbol, member);
}
private static void ReadIntoArray_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
ISchemaValueMember member) {
HandleMemberEndianness_(
- cbsb,
+ sw,
member,
() => {
var sequenceMemberType =
@@ -571,7 +552,7 @@ private static void ReadIntoArray_(
var sequenceType = sequenceTypeInfo.SequenceType;
if (sequenceType.IsISequence()) {
- cbsb.WriteLine($"this.{member.Name}.Read({READER});");
+ sw.WriteLine($"this.{member.Name}.Read({READER});");
return;
}
@@ -589,10 +570,10 @@ private static void ReadIntoArray_(
var label = SchemaGeneratorUtil.GetPrimitiveLabel(
primitiveElementType.PrimitiveType);
if (!primitiveElementType.IsReadOnly) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{READER}.Read{label}s(this.{member.Name});");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{READER}.Assert{label}s(this.{member.Name});");
}
@@ -603,13 +584,13 @@ private static void ReadIntoArray_(
if (!primitiveElementType.IsReadOnly) {
var arrayLengthName = sequenceTypeInfo.LengthName;
- cbsb.EnterBlock(
+ sw.EnterBlock(
$"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)")
.WriteLine(
$"this.{member.Name}[i] = {GetReadPrimitiveText_(sourceSymbol, primitiveElementType)};")
.ExitBlock();
} else {
- cbsb.EnterBlock(
+ sw.EnterBlock(
$"foreach (var e in this.{member.Name})")
.WriteLine(
$"{GetAssertPrimitiveText_(
@@ -623,31 +604,31 @@ private static void ReadIntoArray_(
if (elementType is IContainerMemberType containerElementType) {
if (!containerElementType.TypeSymbol.IsStruct()) {
- cbsb.EnterBlock(
+ sw.EnterBlock(
$"foreach (var e in this.{member.Name})");
if (containerElementType.IsChild) {
- cbsb.WriteLine("e.Parent = this;");
+ sw.WriteLine("e.Parent = this;");
}
- cbsb.WriteLine($"e.Read({READER});");
- cbsb.ExitBlock();
+ sw.WriteLine($"e.Read({READER});");
+ sw.ExitBlock();
} else {
var arrayLengthName = sequenceTypeInfo.LengthName;
- cbsb.EnterBlock(
+ sw.EnterBlock(
$"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)");
- cbsb.WriteLine(
+ sw.WriteLine(
$"var e = this.{member.Name}[i];");
if (containerElementType.IsChild) {
- cbsb.WriteLine("e.Parent = this;");
+ sw.WriteLine("e.Parent = this;");
}
- cbsb.WriteLine($"e.Read({READER});");
- cbsb.WriteLine(
+ sw.WriteLine($"e.Read({READER});");
+ sw.WriteLine(
$"this.{member.Name}[i] = e;");
- cbsb.ExitBlock();
+ sw.ExitBlock();
}
return;
@@ -676,7 +657,8 @@ private static string GetReadPrimitiveText_(
}
var castText = "";
- if (primitiveMemberType.UseAltFormat && !isBoolean &&
+ if (primitiveMemberType.UseAltFormat &&
+ !isBoolean &&
primitiveType !=
altFormat.AsPrimitiveType().GetUnderlyingPrimitiveType()) {
var castType = primitiveType == SchemaPrimitiveType.ENUM
diff --git a/Schema/src/binary/text/BinarySchemaWriterGenerator.cs b/Schema/src/binary/text/BinarySchemaWriterGenerator.cs
index c1bb3e0..86a2a16 100644
--- a/Schema/src/binary/text/BinarySchemaWriterGenerator.cs
+++ b/Schema/src/binary/text/BinarySchemaWriterGenerator.cs
@@ -20,13 +20,8 @@ public class BinarySchemaWriterGenerator {
public string Generate(IBinarySchemaContainer container) {
var typeSymbol = container.TypeSymbol;
- var typeNamespace = typeSymbol.GetFullyQualifiedNamespace();
-
- var declaringTypes =
- SymbolTypeUtil.GetDeclaringTypesDownward(typeSymbol);
-
var sb = new StringBuilder();
- using var cbsb = new CurlyBracketTextWriter(new StringWriter(sb));
+ using var sw = new SourceWriter(new StringWriter(sb));
{
var dependencies = new List { "System", "schema.binary" };
@@ -45,75 +40,61 @@ public string Generate(IBinarySchemaContainer container) {
dependencies.Sort(StringComparer.Ordinal);
foreach (var dependency in dependencies) {
- cbsb.WriteLine($"using {dependency};");
+ sw.WriteLine($"using {dependency};");
}
- cbsb.WriteLine("");
- }
-
- // TODO: Handle fancier cases here
- if (typeNamespace != null) {
- cbsb.EnterBlock($"namespace {typeNamespace}");
+ sw.WriteLine("");
}
- foreach (var declaringType in declaringTypes) {
- cbsb.EnterBlock(declaringType
- .GetQualifiersAndNameAndGenericParametersFor());
- }
-
- cbsb.EnterBlock(typeSymbol.GetQualifiersAndNameAndGenericParametersFor());
-
- cbsb.EnterBlock($"public void Write(IBinaryWriter {WRITER})");
- {
- var hasLocalPositions = container.LocalPositions;
- if (hasLocalPositions) {
- cbsb.WriteLine($"{WRITER}.PushLocalSpace();");
- }
-
- var hasEndianness = container.Endianness != null;
- if (hasEndianness) {
- cbsb.WriteLine(
- $"{WRITER}.PushContainerEndianness({SchemaGeneratorUtil.GetEndiannessName(container.Endianness.Value)});");
- }
-
- foreach (var member in container.Members.OfType()) {
- BinarySchemaWriterGenerator.WriteValueMember_(
- cbsb,
- typeSymbol,
- member);
- }
+ sw.WriteNamespaceAndParentTypeBlocks(
+ typeSymbol,
+ () => {
+ sw.EnterBlock(
+ typeSymbol.GetQualifiersAndNameAndGenericParametersFor());
+
+ sw.EnterBlock($"public void Write(IBinaryWriter {WRITER})");
+ {
+ var hasLocalPositions = container.LocalPositions;
+ if (hasLocalPositions) {
+ sw.WriteLine($"{WRITER}.PushLocalSpace();");
+ }
- if (hasEndianness) {
- cbsb.WriteLine($"{WRITER}.PopEndianness();");
- }
+ var hasEndianness = container.Endianness != null;
+ if (hasEndianness) {
+ sw.WriteLine(
+ $"{WRITER}.PushContainerEndianness({SchemaGeneratorUtil.GetEndiannessName(container.Endianness.Value)});");
+ }
- if (hasLocalPositions) {
- cbsb.WriteLine($"{WRITER}.PopLocalSpace();");
- }
- }
- cbsb.ExitBlock();
+ foreach (var member in container.Members
+ .OfType()) {
+ BinarySchemaWriterGenerator.WriteValueMember_(
+ sw,
+ typeSymbol,
+ member);
+ }
- // TODO: Handle fancier cases here
+ if (hasEndianness) {
+ sw.WriteLine($"{WRITER}.PopEndianness();");
+ }
- // type
- cbsb.ExitBlock();
+ if (hasLocalPositions) {
+ sw.WriteLine($"{WRITER}.PopLocalSpace();");
+ }
+ }
+ sw.ExitBlock();
- // parent types
- foreach (var declaringType in declaringTypes) {
- cbsb.ExitBlock();
- }
+ // TODO: Handle fancier cases here
- // namespace
- if (typeNamespace != null) {
- cbsb.ExitBlock();
- }
+ // type
+ sw.ExitBlock();
+ });
var generatedCode = sb.ToString();
return generatedCode;
}
private static void WriteValueMember_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ITypeSymbol sourceSymbol,
ISchemaValueMember member) {
if (member.IsSkipped) {
@@ -128,12 +109,12 @@ private static void WriteValueMember_(
member.MemberType is not IContainerMemberType;
var ifBoolean = member.IfBoolean;
if (ifBoolean?.SourceType == IfBooleanSourceType.IMMEDIATE_VALUE) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{GetWritePrimitiveText_(SchemaPrimitiveType.BOOLEAN, ifBoolean.ImmediateBooleanType.AsNumberType(), $"this.{member.Name} != null")};");
}
if (shouldSkipWhenNull) {
- cbsb.EnterBlock($"if (this.{member.Name} != null)");
+ sw.EnterBlock($"if (this.{member.Name} != null)");
}
var memberType = member.MemberType;
@@ -143,22 +124,22 @@ private static void WriteValueMember_(
switch (memberType) {
case IPrimitiveMemberType: {
- BinarySchemaWriterGenerator.WritePrimitive_(cbsb, member);
+ BinarySchemaWriterGenerator.WritePrimitive_(sw, member);
break;
}
case IStringType: {
- BinarySchemaWriterGenerator.WriteString_(cbsb, member);
+ BinarySchemaWriterGenerator.WriteString_(sw, member);
break;
}
case IContainerMemberType containerMemberType: {
BinarySchemaWriterGenerator.WriteContainer_(
- cbsb,
+ sw,
containerMemberType,
member);
break;
}
case ISequenceMemberType: {
- BinarySchemaWriterGenerator.WriteArray_(cbsb, member);
+ BinarySchemaWriterGenerator.WriteArray_(sw, member);
break;
}
default:
@@ -167,12 +148,12 @@ private static void WriteValueMember_(
}
if (shouldSkipWhenNull) {
- cbsb.ExitBlock();
+ sw.ExitBlock();
}
}
private static void Align_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
var align = member.Align;
if (align == null) {
@@ -183,39 +164,39 @@ private static void Align_(
AlignSourceType.CONST => $"{align.ConstAlign}",
AlignSourceType.OTHER_MEMBER => $"{align.OtherMember.Name}"
};
- cbsb.WriteLine($"{WRITER}.Align({valueName});");
+ sw.WriteLine($"{WRITER}.Align({valueName});");
}
private static void HandleMemberEndiannessAndTracking_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member,
Action handler) {
- BinarySchemaWriterGenerator.Align_(cbsb, member);
+ BinarySchemaWriterGenerator.Align_(sw, member);
var hasEndianness = member.Endianness != null;
if (hasEndianness) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.PushMemberEndianness({SchemaGeneratorUtil.GetEndiannessName(member.Endianness.Value)});");
}
var shouldTrackStartAndEnd = member.TrackStartAndEnd;
if (shouldTrackStartAndEnd) {
- cbsb.WriteLine($"{WRITER}.MarkStartOfMember(\"{member.Name}\");");
+ sw.WriteLine($"{WRITER}.MarkStartOfMember(\"{member.Name}\");");
}
handler();
if (shouldTrackStartAndEnd) {
- cbsb.WriteLine($"{WRITER}.MarkEndOfMember();");
+ sw.WriteLine($"{WRITER}.MarkEndOfMember();");
}
if (hasEndianness) {
- cbsb.WriteLine($"{WRITER}.PopEndianness();");
+ sw.WriteLine($"{WRITER}.PopEndianness();");
}
}
private static void WritePrimitive_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
var primitiveMemberType = member.MemberType as IPrimitiveMemberType;
if (primitiveMemberType == null) {
@@ -228,7 +209,7 @@ private static void WritePrimitive_(
var primitiveType = primitiveMemberType.PrimitiveType;
HandleMemberEndiannessAndTracking_(
- cbsb,
+ sw,
member,
() => {
var writeType = useAltFormat
@@ -253,7 +234,7 @@ private static void WritePrimitive_(
if (isLengthOfString) {
accessText = $"{lengthOfStringMembers[0].Name}.Length";
if (lengthOfStringMembers.Length > 1) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"Asserts.AllEqual({string.Join(", ", lengthOfStringMembers.Select(member => $"{member.Name}.Length"))});");
}
}
@@ -268,7 +249,7 @@ private static void WritePrimitive_(
(first.MemberTypeInfo as ISequenceTypeInfo).LengthName;
accessText = $"{first.Name}.{firstLengthName}";
if (lengthOfSequenceMembers.Length > 1) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"Asserts.AllEqual({string.Join(", ", lengthOfSequenceMembers.Select(
member => {
var lengthName =
@@ -280,13 +261,13 @@ private static void WritePrimitive_(
if ((isLengthOfString || isLengthOfSequence) &&
!primitiveType.AsIntegerType().CanAcceptAnInt32()) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{GetWritePrimitiveText_(
SchemaPrimitiveType.INT32,
primitiveType.AsNumberType(),
accessText)};");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{GetWritePrimitiveText_(primitiveMemberType, accessText)};");
}
} else {
@@ -321,17 +302,17 @@ private static void WritePrimitive_(
accessText = $"{WRITER}.GetAbsoluteLength()";
}
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.Write{writeTypeLabel}Delayed({accessText}{castText});");
}
});
}
private static void WriteString_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
HandleMemberEndiannessAndTracking_(
- cbsb,
+ sw,
member,
() => {
var stringType =
@@ -352,11 +333,11 @@ private static void WriteString_(
if (stringType.LengthSourceType ==
StringLengthSourceType.NULL_TERMINATED) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.WriteStringNT({encodingTypeWithComma}this.{member.Name});");
} else if (stringType.LengthSourceType ==
StringLengthSourceType.CONST) {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.WriteStringWithExactLength({encodingTypeWithComma}this.{member.Name}, {stringType.ConstLength});");
} else if (stringType.LengthSourceType ==
StringLengthSourceType.IMMEDIATE_VALUE) {
@@ -373,40 +354,40 @@ private static void WriteString_(
var accessText = $"this.{member.Name}.Length";
var writeType = stringType.ImmediateLengthType.GetIntLabel();
- cbsb.WriteLine(
- $"{WRITER}.Write{writeType}({castText}{accessText});")
- .WriteLine(
- $"{WRITER}.WriteString({encodingTypeWithComma}this.{member.Name});");
+ sw.WriteLine(
+ $"{WRITER}.Write{writeType}({castText}{accessText});")
+ .WriteLine(
+ $"{WRITER}.WriteString({encodingTypeWithComma}this.{member.Name});");
} else {
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.WriteString({encodingTypeWithComma}this.{member.Name});");
}
});
}
private static void WriteContainer_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
IContainerMemberType containerMemberType,
ISchemaValueMember member) {
var memberName = member.Name;
if (containerMemberType.IsChild) {
- cbsb.WriteLine($"this.{memberName}.Parent = this;");
+ sw.WriteLine($"this.{memberName}.Parent = this;");
}
HandleMemberEndiannessAndTracking_(
- cbsb,
+ sw,
member,
() => {
if (containerMemberType.TypeInfo.IsNullable) {
- cbsb.WriteLine($"this.{memberName}?.Write({WRITER});");
+ sw.WriteLine($"this.{memberName}?.Write({WRITER});");
} else {
- cbsb.WriteLine($"this.{memberName}.Write({WRITER});");
+ sw.WriteLine($"this.{memberName}.Write({WRITER});");
}
});
}
private static void WriteArray_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
ISchemaValueMember member) {
var sequenceMemberType =
Asserts.CastNonnull(member.MemberType as ISequenceMemberType);
@@ -420,18 +401,18 @@ private static void WriteArray_(
var arrayLengthName = sequenceMemberType.SequenceTypeInfo.LengthName;
var arrayLengthAccessor = $"this.{member.Name}.{arrayLengthName}";
- cbsb.WriteLine(
+ sw.WriteLine(
$"{GetWritePrimitiveText_(SchemaPrimitiveType.INT32, sequenceMemberType.ImmediateLengthType.AsNumberType(), arrayLengthAccessor)};");
}
}
- BinarySchemaWriterGenerator.WriteIntoArray_(cbsb, member);
+ BinarySchemaWriterGenerator.WriteIntoArray_(sw, member);
}
- private static void WriteIntoArray_(ICurlyBracketTextWriter cbsb,
+ private static void WriteIntoArray_(ISourceWriter sw,
ISchemaValueMember member) {
HandleMemberEndiannessAndTracking_(
- cbsb,
+ sw,
member,
() => {
var sequenceMemberType =
@@ -440,7 +421,7 @@ private static void WriteIntoArray_(ICurlyBracketTextWriter cbsb,
var sequenceType = sequenceTypeInfo.SequenceType;
if (sequenceType.IsISequence()) {
- cbsb.WriteLine($"this.{member.Name}.Write({WRITER});");
+ sw.WriteLine($"this.{member.Name}.Write({WRITER});");
return;
}
@@ -459,30 +440,30 @@ private static void WriteIntoArray_(ICurlyBracketTextWriter cbsb,
var label =
SchemaGeneratorUtil.GetPrimitiveLabel(
primitiveElementType.PrimitiveType);
- cbsb.WriteLine(
+ sw.WriteLine(
$"{WRITER}.Write{label}s(this.{member.Name});");
return;
}
// Primitives that *do* need to be cast have to be written individually.
var arrayLengthName = sequenceTypeInfo.LengthName;
- cbsb.EnterBlock(
- $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)")
- .WriteLine(
- $"{GetWritePrimitiveText_(primitiveElementType, $"this.{member.Name}[i]")};")
- .ExitBlock();
+ sw.EnterBlock(
+ $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)")
+ .WriteLine(
+ $"{GetWritePrimitiveText_(primitiveElementType, $"this.{member.Name}[i]")};")
+ .ExitBlock();
return;
}
if (elementType is IContainerMemberType containerElementType) {
- cbsb.EnterBlock($"foreach (var e in this.{member.Name})");
+ sw.EnterBlock($"foreach (var e in this.{member.Name})");
if (containerElementType.IsChild) {
- cbsb.WriteLine("e.Parent = this;");
+ sw.WriteLine("e.Parent = this;");
}
- cbsb.WriteLine($"e.Write({WRITER});")
- .ExitBlock();
+ sw.WriteLine($"e.Write({WRITER});")
+ .ExitBlock();
return;
}
diff --git a/Schema/src/readOnly/ReadOnlyTypeGenerator.cs b/Schema/src/readOnly/ReadOnlyTypeGenerator.cs
index bb39133..1f07a49 100644
--- a/Schema/src/readOnly/ReadOnlyTypeGenerator.cs
+++ b/Schema/src/readOnly/ReadOnlyTypeGenerator.cs
@@ -52,132 +52,118 @@ internal override bool FilterNamedTypesBeforeGenerating(
public string GenerateSourceForNamedType(INamedTypeSymbol typeSymbol,
SemanticModel semanticModel,
TypeDeclarationSyntax syntax) {
- var typeNamespace = typeSymbol.GetFullyQualifiedNamespace();
-
- var declaringTypes = typeSymbol.GetDeclaringTypesDownward();
-
var sb = new StringBuilder();
- using var cbsb = new CurlyBracketTextWriter(new StringWriter(sb));
+ using var sw = new SourceWriter(new StringWriter(sb));
+
+ sw.WriteNamespaceAndParentTypeBlocks(
+ typeSymbol,
+ () => {
+ var interfaceName = typeSymbol.GetConstInterfaceName();
+
+ var constMembers
+ = parser_
+ .ParseMembers(typeSymbol)
+ .Where(parsedMember => {
+ var (parseStatus, memberSymbol, _, _) = parsedMember;
+ if (parseStatus ==
+ TypeInfoParser.ParseStatus
+ .NOT_A_FIELD_OR_PROPERTY_OR_METHOD) {
+ return false;
+ }
+
+ if (memberSymbol.DeclaredAccessibility is not (
+ Accessibility.Public
+ or Accessibility.Internal)) {
+ return false;
+ }
+
+ if (memberSymbol is IFieldSymbol) {
+ return false;
+ }
+
+ if (memberSymbol is IPropertySymbol) {
+ return false;
+ }
+
+ if (memberSymbol is IMethodSymbol &&
+ !memberSymbol.Name.StartsWith("get_") &&
+ !memberSymbol.HasAttribute()) {
+ return false;
+ }
+
+ return true;
+ })
+ .Select(parsedMember => (IMethodSymbol) parsedMember.Item2)
+ .ToArray();
- // TODO: Handle fancier cases here
- if (typeNamespace != null) {
- cbsb.EnterBlock($"namespace {typeNamespace}");
- }
+ // Class
+ {
+ var blockPrefix =
+ typeSymbol.GetQualifiersAndNameAndGenericParametersFor() +
+ " : " +
+ typeSymbol.GetNameAndGenericParametersFor(interfaceName);
- foreach (var declaringType in declaringTypes) {
- cbsb.EnterBlock(declaringType
- .GetQualifiersAndNameAndGenericParametersFor());
- }
-
- var interfaceName = typeSymbol.GetConstInterfaceName();
-
- var constMembers
- = parser_
- .ParseMembers(typeSymbol)
- .Where(parsedMember => {
- var (parseStatus, memberSymbol, _, _) = parsedMember;
- if (parseStatus ==
- TypeInfoParser.ParseStatus
- .NOT_A_FIELD_OR_PROPERTY_OR_METHOD) {
- return false;
- }
-
- if (memberSymbol.DeclaredAccessibility is not (
- Accessibility.Public or Accessibility.Internal)) {
- return false;
- }
-
- if (memberSymbol is IFieldSymbol) {
- return false;
- }
-
- if (memberSymbol is IPropertySymbol) {
- return false;
- }
-
- if (memberSymbol is IMethodSymbol &&
- !memberSymbol.Name.StartsWith("get_") &&
- !memberSymbol.HasAttribute()) {
- return false;
- }
-
- return true;
- })
- .Select(parsedMember => (IMethodSymbol) parsedMember.Item2)
- .ToArray();
-
- // Class
- {
- var blockPrefix =
- typeSymbol.GetQualifiersAndNameAndGenericParametersFor() +
- " : " +
- typeSymbol.GetNameAndGenericParametersFor(interfaceName);
-
- if (constMembers.Length == 0) {
- cbsb.Write(blockPrefix).WriteLine(";");
- } else {
- cbsb.EnterBlock(blockPrefix);
- WriteMembers_(cbsb,
- typeSymbol,
- constMembers,
- semanticModel,
- syntax,
- interfaceName);
- cbsb.ExitBlock();
- }
- }
- cbsb.WriteLine("");
-
- // Interface
- {
- cbsb.Write(
- SymbolTypeUtil.AccessibilityToModifier(
- typeSymbol.DeclaredAccessibility));
- cbsb.Write(" interface ");
-
- var blockPrefix = interfaceName;
- blockPrefix
- += typeSymbol.GetGenericParametersWithVarianceForReadOnlyVersion(
- constMembers);
- var parentConstNames =
- GetDirectBaseTypeAndInterfaces_(typeSymbol)
- .Where(i => i.HasAttribute() ||
- IsTypeAlreadyConst_(i))
- .Select(i => typeSymbol
- .GetQualifiedNameAndGenericsOrReadOnlyFromCurrentSymbol(
- i,
- semanticModel,
- syntax))
- .ToArray();
- if (parentConstNames.Length > 0) {
- blockPrefix += " : " + string.Join(", ", parentConstNames);
- }
+ if (constMembers.Length == 0) {
+ sw.Write(blockPrefix).WriteLine(";");
+ } else {
+ sw.EnterBlock(blockPrefix);
+ WriteMembers_(sw,
+ typeSymbol,
+ constMembers,
+ semanticModel,
+ syntax,
+ interfaceName);
+ sw.ExitBlock();
+ }
+ }
+ sw.WriteLine("");
+
+ // Interface
+ {
+ sw.Write(
+ SymbolTypeUtil.AccessibilityToModifier(
+ typeSymbol.DeclaredAccessibility));
+ sw.Write(" interface ");
+
+ var blockPrefix = interfaceName;
+ blockPrefix
+ += typeSymbol
+ .GetGenericParametersWithVarianceForReadOnlyVersion(
+ constMembers);
+ var parentConstNames =
+ GetDirectBaseTypeAndInterfaces_(typeSymbol)
+ .Where(i => i.HasAttribute() ||
+ IsTypeAlreadyConst_(i))
+ .Select(i => typeSymbol
+ .GetQualifiedNameAndGenericsOrReadOnlyFromCurrentSymbol(
+ i,
+ semanticModel,
+ syntax))
+ .ToArray();
+ if (parentConstNames.Length > 0) {
+ blockPrefix += " : " + string.Join(", ", parentConstNames);
+ }
- blockPrefix += typeSymbol.GetTypeConstraintsOrReadonly(
- typeSymbol.TypeParameters,
- semanticModel,
- syntax);
-
- if (constMembers.Length == 0) {
- cbsb.Write(blockPrefix).WriteLine(";");
- } else {
- cbsb.EnterBlock(blockPrefix);
- WriteMembers_(cbsb, typeSymbol, constMembers, semanticModel, syntax);
- cbsb.ExitBlock();
- }
+ blockPrefix += typeSymbol.GetTypeConstraintsOrReadonly(
+ typeSymbol.TypeParameters,
+ semanticModel,
+ syntax);
- // parent types
- foreach (var _ in declaringTypes) {
- cbsb.ExitBlock();
- }
-
- // namespace
- if (typeNamespace != null) {
- cbsb.ExitBlock();
- }
+ if (constMembers.Length == 0) {
+ sw.Write(blockPrefix).WriteLine(";");
+ } else {
+ sw.EnterBlock(blockPrefix);
+ WriteMembers_(sw,
+ typeSymbol,
+ constMembers,
+ semanticModel,
+ syntax);
+ sw.ExitBlock();
+ }
+ }
+ });
- return sb.ToString();
- }
+ return sb.ToString();
}
private static bool IsTypeAlreadyConst_(INamedTypeSymbol typeSymbol) {
@@ -221,7 +207,7 @@ private static bool IsTypeAlreadyConst_(INamedTypeSymbol typeSymbol) {
}
private static void WriteMembers_(
- ICurlyBracketTextWriter cbsb,
+ ISourceWriter sw,
INamedTypeSymbol typeSymbol,
IReadOnlyList constMembers,
SemanticModel semanticModel,
@@ -231,14 +217,14 @@ private static void WriteMembers_(
var memberTypeSymbol = memberSymbol.ReturnType;
if (interfaceName == null) {
- cbsb.Write(SymbolTypeUtil.AccessibilityToModifier(
+ sw.Write(SymbolTypeUtil.AccessibilityToModifier(
typeSymbol.DeclaredAccessibility))
.Write(" ");
}
IPropertySymbol? associatedPropertySymbol
= memberSymbol.AssociatedSymbol as IPropertySymbol;
- cbsb.Write(
+ sw.Write(
typeSymbol
.GetQualifiedNameAndGenericsOrReadOnlyFromCurrentSymbol(
memberTypeSymbol,
@@ -248,7 +234,7 @@ private static void WriteMembers_(
.Write(" ");
if (interfaceName != null) {
- cbsb.Write(interfaceName)
+ sw.Write(interfaceName)
.Write(typeSymbol.GetGenericParameters())
.Write(".");
}
@@ -260,17 +246,17 @@ var isIndexer
if (!isIndexer) {
propertyAccessName = propertyAccessName.EscapeKeyword();
- cbsb.Write(memberSymbol.Name.Substring(4).EscapeKeyword());
+ sw.Write(memberSymbol.Name.Substring(4).EscapeKeyword());
} else {
propertyAccessName = "this";
- cbsb.Write("this[");
+ sw.Write("this[");
for (var i = 0; i < indexerParameterSymbols.Length; ++i) {
if (i > 0) {
- cbsb.Write(", ");
+ sw.Write(", ");
}
var parameterSymbol = indexerParameterSymbols[i];
- cbsb.Write(
+ sw.Write(
typeSymbol.GetQualifiedNameAndGenericsFromCurrentSymbol(
parameterSymbol.Type,
semanticModel,
@@ -280,13 +266,13 @@ var isIndexer
.Write(parameterSymbol.Name.EscapeKeyword());
}
- cbsb.Write("]");
+ sw.Write("]");
}
if (interfaceName == null) {
- cbsb.WriteLine(" { get; }");
+ sw.WriteLine(" { get; }");
} else {
- cbsb.Write(" => ")
+ sw.Write(" => ")
.Write(typeSymbol.GetCStyleCastToReadOnlyIfNeeded(
associatedPropertySymbol,
memberSymbol.ReturnType,
@@ -295,101 +281,101 @@ var isIndexer
.Write(propertyAccessName);
if (isIndexer) {
- cbsb.Write("[");
+ sw.Write("[");
for (var i = 0; i < memberSymbol.Parameters.Length; ++i) {
if (i > 0) {
- cbsb.Write(", ");
+ sw.Write(", ");
}
var parameterSymbol = memberSymbol.Parameters[i];
- cbsb.Write(parameterSymbol.Name.EscapeKeyword());
+ sw.Write(parameterSymbol.Name.EscapeKeyword());
}
- cbsb.Write("]");
+ sw.Write("]");
}
- cbsb.WriteLine(";");
+ sw.WriteLine(";");
}
}
// Method
else {
var accessName = memberSymbol.Name.EscapeKeyword();
- cbsb.Write(accessName);
- cbsb.Write(memberSymbol.TypeParameters
+ sw.Write(accessName);
+ sw.Write(memberSymbol.TypeParameters
.GetGenericParameters());
- cbsb.Write("(");
+ sw.Write("(");
for (var i = 0; i < memberSymbol.Parameters.Length; ++i) {
if (i > 0) {
- cbsb.Write(", ");
+ sw.Write(", ");
}
var parameterSymbol = memberSymbol.Parameters[i];
if (parameterSymbol.IsParams) {
- cbsb.Write("params ");
+ sw.Write("params ");
}
var refKindString = parameterSymbol.RefKind.GetRefKindString();
if (refKindString.Length > 0) {
- cbsb.Write(refKindString).Write(" ");
+ sw.Write(refKindString).Write(" ");
}
- cbsb.Write(typeSymbol.GetQualifiedNameAndGenericsFromCurrentSymbol(
- parameterSymbol.Type,
- semanticModel,
- syntax,
- parameterSymbol))
+ sw.Write(
+ typeSymbol.GetQualifiedNameAndGenericsFromCurrentSymbol(
+ parameterSymbol.Type,
+ semanticModel,
+ syntax,
+ parameterSymbol))
.Write(" ")
.Write(parameterSymbol.Name.EscapeKeyword());
-
if (interfaceName == null &&
parameterSymbol.HasExplicitDefaultValue) {
var defaultValueType = parameterSymbol.Type.UnwrapNullable();
-
- cbsb.Write(" = ");
+
+ sw.Write(" = ");
var explicitDefaultValue = parameterSymbol.ExplicitDefaultValue;
if (defaultValueType.IsEnum(out _) &&
explicitDefaultValue != null) {
- cbsb.Write(
+ sw.Write(
$"({typeSymbol.GetQualifiedNameFromCurrentSymbol(defaultValueType)}) {explicitDefaultValue}");
} else {
switch (explicitDefaultValue) {
case null:
- cbsb.Write("null");
+ sw.Write("null");
break;
case char:
- cbsb.Write($"'{explicitDefaultValue}'");
+ sw.Write($"'{explicitDefaultValue}'");
break;
case string:
- cbsb.Write($"\"{explicitDefaultValue}\"");
+ sw.Write($"\"{explicitDefaultValue}\"");
break;
case bool boolValue:
- cbsb.Write(boolValue ? "true" : "false");
+ sw.Write(boolValue ? "true" : "false");
break;
default:
- cbsb.Write(explicitDefaultValue.ToString());
+ sw.Write(explicitDefaultValue.ToString());
break;
}
}
}
}
- cbsb.Write(")");
+ sw.Write(")");
if (interfaceName == null) {
- cbsb.Write(typeSymbol.GetTypeConstraintsOrReadonly(
+ sw.Write(typeSymbol.GetTypeConstraintsOrReadonly(
memberSymbol.TypeParameters,
semanticModel,
syntax));
}
if (interfaceName == null) {
- cbsb.WriteLine(";");
+ sw.WriteLine(";");
} else {
- cbsb.Write(" => ")
+ sw.Write(" => ")
.Write(typeSymbol.GetCStyleCastToReadOnlyIfNeeded(
memberSymbol,
memberSymbol.ReturnType,
@@ -400,20 +386,20 @@ var isIndexer
.Write("(");
for (var i = 0; i < memberSymbol.Parameters.Length; ++i) {
if (i > 0) {
- cbsb.Write(", ");
+ sw.Write(", ");
}
var parameterSymbol = memberSymbol.Parameters[i];
var refKindString = parameterSymbol.RefKind.GetRefKindString();
if (refKindString.Length > 0) {
- cbsb.Write(refKindString).Write(" ");
+ sw.Write(refKindString).Write(" ");
}
- cbsb.Write(parameterSymbol.Name.EscapeKeyword());
+ sw.Write(parameterSymbol.Name.EscapeKeyword());
}
- cbsb.WriteLine(");");
+ sw.WriteLine(");");
}
}
}
@@ -446,12 +432,13 @@ var parentInterfaces
internal static class ReadOnlyTypeGeneratorUtil {
public const string PREFIX = "IReadOnly";
- public static string GetQualifiedNameAndGenericsOrReadOnlyFromCurrentSymbol(
- this ITypeSymbol sourceSymbol,
- ITypeSymbol referencedSymbol,
- SemanticModel semanticModel,
- TypeDeclarationSyntax sourceDeclarationSyntax,
- ISymbol? memberSymbol = null)
+ public static string
+ GetQualifiedNameAndGenericsOrReadOnlyFromCurrentSymbol(
+ this ITypeSymbol sourceSymbol,
+ ITypeSymbol referencedSymbol,
+ SemanticModel semanticModel,
+ TypeDeclarationSyntax sourceDeclarationSyntax,
+ ISymbol? memberSymbol = null)
=> sourceSymbol.GetQualifiedNameFromCurrentSymbol(
referencedSymbol,
memberSymbol,
@@ -520,14 +507,16 @@ private static IEnumerable GetTypeConstraintNames_(
}
if (typeParameter.HasReferenceTypeConstraint) {
- yield return typeParameter.ReferenceTypeConstraintNullableAnnotation ==
+ yield return typeParameter
+ .ReferenceTypeConstraintNullableAnnotation ==
NullableAnnotation.Annotated
? "class?"
: "class";
}
- if (typeParameter is
- { HasValueTypeConstraint: true, HasUnmanagedTypeConstraint: false }) {
+ if (typeParameter is {
+ HasValueTypeConstraint: true, HasUnmanagedTypeConstraint: false
+ }) {
yield return "struct";
}
@@ -537,7 +526,9 @@ private static IEnumerable GetTypeConstraintNames_(
constraintType,
typeParameter,
ConvertName_,
- r => GetNamespaceOfType(r, semanticModel, sourceDeclarationSyntax));
+ r => GetNamespaceOfType(r,
+ semanticModel,
+ sourceDeclarationSyntax));
yield return typeParameter.ConstraintNullableAnnotations[i] ==
NullableAnnotation.Annotated
diff --git a/Schema/src/util/text/CurlyBracketTextWriter.cs b/Schema/src/util/text/CurlyBracketTextWriter.cs
deleted file mode 100644
index 2406ad0..0000000
--- a/Schema/src/util/text/CurlyBracketTextWriter.cs
+++ /dev/null
@@ -1,100 +0,0 @@
-using System;
-using System.IO;
-
-namespace schema.util.text {
- public interface ICurlyBracketTextWriter {
- public ICurlyBracketTextWriter EnterBlock(string prefix = "");
- public ICurlyBracketTextWriter Write(string text);
- public ICurlyBracketTextWriter WriteLine(string text);
- public ICurlyBracketTextWriter ExitBlock();
- }
-
- public sealed class CurlyBracketTextWriter
- : ICurlyBracketTextWriter,
- IDisposable {
- private readonly TextWriter impl_;
- private int indentLevel_ = 0;
- private bool hasIndentedOnCurrentLine_ = false;
-
- public CurlyBracketTextWriter(TextWriter impl) {
- this.impl_ = impl;
- }
-
- ~CurlyBracketTextWriter() => this.ReleaseUnmanagedResources_();
-
- public void Dispose() {
- this.ReleaseUnmanagedResources_();
- GC.SuppressFinalize(this);
- }
-
- private void ReleaseUnmanagedResources_() {
- this.impl_.Dispose();
- }
-
- public ICurlyBracketTextWriter EnterBlock(string prefix = "") {
- if (prefix.Length > 0) {
- prefix = $"{prefix} ";
- }
-
- this.WriteLine($"{prefix}{{");
- return this;
- }
-
- public ICurlyBracketTextWriter Write(string text) {
- var lines = text.Split('\n');
- for (var i = 0; i < lines.Length; ++i) {
- var line = lines[i];
- var isLastLine = !(i < lines.Length - 1);
-
- if (isLastLine && line.Length == 0) {
- break;
- }
-
- foreach (var c in line) {
- if (c == '}') {
- --this.indentLevel_;
-
- if (this.indentLevel_ < 0) {
- throw new Exception("Exited an extra block!");
- }
- }
- }
-
- if (!isLastLine) {
- this.TryToPrintIndent_();
- this.impl_.WriteLine(line);
- this.hasIndentedOnCurrentLine_ = false;
- } else {
- this.TryToPrintIndent_();
- this.impl_.Write(line);
- }
-
- foreach (var c in line) {
- if (c == '{') {
- ++this.indentLevel_;
- }
- }
- }
-
- return this;
- }
-
- public ICurlyBracketTextWriter ExitBlock() {
- this.WriteLine("}");
- return this;
- }
-
- public ICurlyBracketTextWriter WriteLine(string text) => Write(text + '\n');
-
- private void TryToPrintIndent_() {
- if (this.hasIndentedOnCurrentLine_) {
- return;
- }
-
- this.hasIndentedOnCurrentLine_ = true;
- for (var i = 0; i < this.indentLevel_; ++i) {
- this.impl_.Write(" ");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/Schema/src/util/text/SourceWriter.cs b/Schema/src/util/text/SourceWriter.cs
new file mode 100644
index 0000000..a41bd16
--- /dev/null
+++ b/Schema/src/util/text/SourceWriter.cs
@@ -0,0 +1,67 @@
+using System;
+using System.IO;
+
+using CommunityToolkit.HighPerformance;
+
+namespace schema.util.text {
+ public interface ISourceWriter : IDisposable {
+ ISourceWriter Write(string text);
+ }
+
+ public sealed class SourceWriter(TextWriter impl) : ISourceWriter {
+ private int indentLevel_;
+ private bool hasIndentedOnCurrentLine_;
+
+ ~SourceWriter() => this.ReleaseUnmanagedResources_();
+
+ public void Dispose() {
+ this.ReleaseUnmanagedResources_();
+ GC.SuppressFinalize(this);
+ }
+
+ private void ReleaseUnmanagedResources_() {
+ impl.Dispose();
+ }
+
+ public ISourceWriter Write(string text) {
+ var lines = text.Split('\n');
+ for (var i = 0; i < lines.Length; ++i) {
+ var line = lines[i];
+ var isLastLine = !(i < lines.Length - 1);
+
+ if (isLastLine && line.Length == 0) {
+ break;
+ }
+
+ this.indentLevel_ -= line.Count('}');
+ if (this.indentLevel_ < 0) {
+ throw new Exception("Exited an extra block!");
+ }
+
+ if (!isLastLine) {
+ this.TryToPrintIndent_();
+ impl.WriteLine(line);
+ this.hasIndentedOnCurrentLine_ = false;
+ } else {
+ this.TryToPrintIndent_();
+ impl.Write(line);
+ }
+
+ this.indentLevel_ += line.Count('{');
+ }
+
+ return this;
+ }
+
+ private void TryToPrintIndent_() {
+ if (this.hasIndentedOnCurrentLine_) {
+ return;
+ }
+
+ this.hasIndentedOnCurrentLine_ = true;
+ for (var i = 0; i < this.indentLevel_; ++i) {
+ impl.Write(" ");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Schema/src/util/text/SourceWriterExtensions.cs b/Schema/src/util/text/SourceWriterExtensions.cs
new file mode 100644
index 0000000..8207558
--- /dev/null
+++ b/Schema/src/util/text/SourceWriterExtensions.cs
@@ -0,0 +1,18 @@
+namespace schema.util.text {
+ public static class SourceWriterExtensions {
+ public static ISourceWriter EnterBlock(this ISourceWriter sw,
+ string prefix = "") {
+ if (prefix.Length > 0) {
+ prefix = $"{prefix} ";
+ }
+
+ return sw.WriteLine($"{prefix}{{");
+ }
+
+ public static ISourceWriter ExitBlock(this ISourceWriter sw)
+ => sw.WriteLine("}");
+
+ public static ISourceWriter WriteLine(this ISourceWriter sw, string text)
+ => sw.Write(text + '\n');
+ }
+}
\ No newline at end of file
diff --git a/Schema/src/util/text/SourceWriterSymbolExtensions.cs b/Schema/src/util/text/SourceWriterSymbolExtensions.cs
new file mode 100644
index 0000000..37567e7
--- /dev/null
+++ b/Schema/src/util/text/SourceWriterSymbolExtensions.cs
@@ -0,0 +1,37 @@
+using System;
+
+using Microsoft.CodeAnalysis;
+
+using schema.util.symbols;
+
+namespace schema.util.text {
+ public static class SourceWriterSymbolExtensions {
+ public static void WriteNamespaceAndParentTypeBlocks(
+ this ISourceWriter sw,
+ INamedTypeSymbol symbol,
+ Action insideBlockHandler) {
+ var fullyQualifiedNamespace = symbol.GetFullyQualifiedNamespace();
+ if (fullyQualifiedNamespace != null) {
+ sw.EnterBlock($"namespace {fullyQualifiedNamespace}");
+ }
+
+ var declaringTypes = symbol.GetDeclaringTypesDownward();
+ foreach (var declaringType in declaringTypes) {
+ sw.EnterBlock(declaringType
+ .GetQualifiersAndNameAndGenericParametersFor());
+ }
+
+ insideBlockHandler();
+
+ // parent types
+ foreach (var _ in declaringTypes) {
+ sw.ExitBlock();
+ }
+
+ // namespace
+ if (fullyQualifiedNamespace != null) {
+ sw.ExitBlock();
+ }
+ }
+ }
+}
\ No newline at end of file