fix: Fixes timer migrations not compiling (#902)
This commit is contained in:
parent
d0aa6320f7
commit
5019ce9694
15 changed files with 1273 additions and 1209 deletions
|
|
@ -23,6 +23,13 @@ namespace SerializableMigration
|
|||
{
|
||||
string RuleName { get; }
|
||||
|
||||
void GenerateMigrationProperty(
|
||||
StringBuilder source,
|
||||
Compilation compilation,
|
||||
string indent,
|
||||
SerializableProperty serializableProperty
|
||||
);
|
||||
|
||||
bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
|
|
@ -37,7 +44,8 @@ namespace SerializableMigration
|
|||
StringBuilder source,
|
||||
string indent,
|
||||
SerializableProperty property,
|
||||
string? parentReference
|
||||
string? parentReference,
|
||||
bool isMigration = false
|
||||
);
|
||||
|
||||
void GenerateSerializationMethod(
|
||||
|
|
|
|||
|
|
@ -18,117 +18,118 @@ using System.Collections.Immutable;
|
|||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class ArrayMigrationRule : MigrationRule
|
||||
{
|
||||
public class ArrayMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(ArrayMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(ArrayMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
|
||||
{
|
||||
if (symbol is not IArrayTypeSymbol arrayTypeSymbol)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ArrayEntry",
|
||||
arrayTypeSymbol.ElementType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var length = serializableArrayType.RuleArguments?.Length?? 0;
|
||||
ruleArguments = new string[length + 2];
|
||||
ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString();
|
||||
ruleArguments[1] = serializableArrayType.Rule;
|
||||
if (length > 0)
|
||||
{
|
||||
Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
|
||||
}
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
var serializableArrayType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ArrayEntry",
|
||||
arrayTypeSymbol.ElementType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var length = serializableArrayType.RuleArguments?.Length?? 0;
|
||||
ruleArguments = new string[length + 2];
|
||||
ruleArguments[0] = arrayTypeSymbol.ElementType.ToDisplayString();
|
||||
ruleArguments[1] = serializableArrayType.Rule;
|
||||
if (length > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
|
||||
var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
|
||||
Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
|
||||
|
||||
var propertyIndex = $"{property.Name}Index";
|
||||
source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableArrayElement = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}[{propertyIndex}]",
|
||||
Type = ruleArguments[0],
|
||||
Rule = arrayElementRule.RuleName,
|
||||
RuleArguments = arrayElementRuleArguments
|
||||
};
|
||||
|
||||
arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference);
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
Array.Copy(serializableArrayType.RuleArguments!, 0, ruleArguments, 2, length);
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
|
||||
var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
|
||||
Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyLength = $"{propertyVarPrefix}Length";
|
||||
source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableArrayElement = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}![{propertyIndex}]",
|
||||
Type = ruleArguments[0],
|
||||
Rule = arrayElementRule.RuleName,
|
||||
RuleArguments = arrayElementRuleArguments
|
||||
};
|
||||
|
||||
arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement);
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
|
||||
var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
|
||||
Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
|
||||
|
||||
var propertyIndex = $"{property.Name}Index";
|
||||
source.AppendLine($"{indent}{property.Name} = new {ruleArguments[0]}[reader.ReadEncodedInt()];");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {property.Name}.Length; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableArrayElement = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}[{propertyIndex}]",
|
||||
Type = ruleArguments[0],
|
||||
Rule = arrayElementRule.RuleName,
|
||||
RuleArguments = arrayElementRuleArguments
|
||||
};
|
||||
|
||||
arrayElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableArrayElement, parentReference);
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var arrayElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![1]];
|
||||
var arrayElementRuleArguments = new string[ruleArguments.Length - 2];
|
||||
Array.Copy(ruleArguments, 2, arrayElementRuleArguments, 0, ruleArguments.Length - 2);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyLength = $"{propertyVarPrefix}Length";
|
||||
source.AppendLine($"{indent}var {propertyLength} = {property.Name}?.Length ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyLength});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyLength}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableArrayElement = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}![{propertyIndex}]",
|
||||
Type = ruleArguments[0],
|
||||
Rule = arrayElementRule.RuleName,
|
||||
RuleArguments = arrayElementRuleArguments
|
||||
};
|
||||
|
||||
arrayElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableArrayElement);
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,230 +20,231 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class DictionaryMigrationRule : MigrationRule
|
||||
{
|
||||
public class DictionaryMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(DictionaryMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(DictionaryMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation))
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsDictionary(compilation))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var keySymbolType = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"KeyEntry",
|
||||
keySymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var valueSymbolType = namedTypeSymbol.TypeArguments[1];
|
||||
|
||||
var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ValueEntry",
|
||||
valueSymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0;
|
||||
var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0;
|
||||
var index = 0;
|
||||
|
||||
ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength];
|
||||
ruleArguments[index++] = extraOptions;
|
||||
ruleArguments[index++] = keySymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = serializableKeyProperty.Rule;
|
||||
ruleArguments[index++] = keyArgumentsLength.ToString();
|
||||
|
||||
if (keyArgumentsLength > 0)
|
||||
{
|
||||
Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
|
||||
index += keyArgumentsLength;
|
||||
}
|
||||
|
||||
ruleArguments[index++] = valueSymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = serializableValueProperty.Rule;
|
||||
ruleArguments[index++] = valueArgumentsLength.ToString();
|
||||
|
||||
if (valueArgumentsLength > 0)
|
||||
{
|
||||
Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
var keySymbolType = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableKeyProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"KeyEntry",
|
||||
keySymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var valueSymbolType = namedTypeSymbol.TypeArguments[1];
|
||||
|
||||
var serializableValueProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ValueEntry",
|
||||
valueSymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1;
|
||||
var keyType = ruleArguments![index++];
|
||||
|
||||
var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyKeyEntry = $"{propertyVarPrefix}Key";
|
||||
var propertyValueEntry = $"{propertyVarPrefix}Value";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};");
|
||||
source.AppendLine($"{indent}{valueType} {propertyValueEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableKeyElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyKeyEntry,
|
||||
Type = keyType,
|
||||
Rule = keyElementRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference);
|
||||
|
||||
var serializableValueElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyValueEntry,
|
||||
Type = valueType,
|
||||
Rule = valueElementRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference);
|
||||
source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
var keyArgumentsLength = serializableKeyProperty.RuleArguments?.Length ?? 0;
|
||||
var valueArgumentsLength = serializableValueProperty.RuleArguments?.Length ?? 0;
|
||||
var index = 0;
|
||||
|
||||
ruleArguments = new string[7 + keyArgumentsLength + valueArgumentsLength];
|
||||
ruleArguments[index++] = extraOptions;
|
||||
ruleArguments[index++] = keySymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = serializableKeyProperty.Rule;
|
||||
ruleArguments[index++] = keyArgumentsLength.ToString();
|
||||
|
||||
if (keyArgumentsLength > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 0;
|
||||
var shouldTidy = ruleArguments![index++].Contains("@Tidy");
|
||||
var keyType = ruleArguments![index++];
|
||||
|
||||
var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyKeyEntry = $"{propertyVarPrefix}Key";
|
||||
var propertyValueEntry = $"{propertyVarPrefix}Value";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableKeyElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyKeyEntry,
|
||||
Type = keyType,
|
||||
Rule = keyElementRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement);
|
||||
|
||||
var serializableValueElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyValueEntry,
|
||||
Type = valueType,
|
||||
Rule = valueElementRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
Array.Copy(serializableKeyProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
|
||||
index += keyArgumentsLength;
|
||||
}
|
||||
|
||||
ruleArguments[index++] = valueSymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = serializableValueProperty.Rule;
|
||||
ruleArguments[index++] = valueArgumentsLength.ToString();
|
||||
|
||||
if (valueArgumentsLength > 0)
|
||||
{
|
||||
Array.Copy(serializableValueProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1;
|
||||
var keyType = ruleArguments![index++];
|
||||
|
||||
var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyKeyEntry = $"{propertyVarPrefix}Key";
|
||||
var propertyValueEntry = $"{propertyVarPrefix}Value";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[1]} {propertyKeyEntry};");
|
||||
source.AppendLine($"{indent}{valueType} {propertyValueEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.Dictionary<{keyType}, {valueType}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableKeyElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyKeyEntry,
|
||||
Type = keyType,
|
||||
Rule = keyElementRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableKeyElement, parentReference);
|
||||
|
||||
var serializableValueElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyValueEntry,
|
||||
Type = valueType,
|
||||
Rule = valueElementRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableValueElement, parentReference);
|
||||
source.AppendLine($"{indent} {propertyName}.Add({propertyKeyEntry}, {propertyValueEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 0;
|
||||
var shouldTidy = ruleArguments![index++].Contains("@Tidy");
|
||||
var keyType = ruleArguments![index++];
|
||||
|
||||
var keyElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments![index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyKeyEntry = $"{propertyVarPrefix}Key";
|
||||
var propertyValueEntry = $"{propertyVarPrefix}Value";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var ({propertyKeyEntry}, {propertyValueEntry}) in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableKeyElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyKeyEntry,
|
||||
Type = keyType,
|
||||
Rule = keyElementRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableKeyElement);
|
||||
|
||||
var serializableValueElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyValueEntry,
|
||||
Type = valueType,
|
||||
Rule = valueElementRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableValueElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,54 +19,55 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class EnumMigrationRule : MigrationRule
|
||||
{
|
||||
public class EnumMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(EnumMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(EnumMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
|
||||
{
|
||||
if (symbol is not ITypeSymbol typeSymbol || !typeSymbol.IsEnum())
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
source.AppendLine($"{indent}{property.Name} = reader.ReadEnum<{property.Type}>();");
|
||||
}
|
||||
|
||||
source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
source.AppendLine($"{indent}writer.WriteEnum<{property.Type}>({property.Name});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,151 +20,152 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class HashSetMigrationRule : MigrationRule
|
||||
{
|
||||
public class HashSetMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(HashSetMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(HashSetMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation))
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsHashSet(compilation))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var setTypeSymbol = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"SetEntry",
|
||||
setTypeSymbol,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
var length = serializableSetType.RuleArguments?.Length ?? 0;
|
||||
ruleArguments = new string[length + 3];
|
||||
ruleArguments[0] = extraOptions;
|
||||
ruleArguments[1] = setTypeSymbol.ToDisplayString();
|
||||
ruleArguments[2] = serializableSetType.Rule;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length);
|
||||
}
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
var setTypeSymbol = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableSetType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"SetEntry",
|
||||
setTypeSymbol,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableSetElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = setElementRule.RuleName,
|
||||
RuleArguments = setElementRuleArguments
|
||||
};
|
||||
|
||||
setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference);
|
||||
source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
var length = serializableSetType.RuleArguments?.Length ?? 0;
|
||||
ruleArguments = new string[length + 3];
|
||||
ruleArguments[0] = extraOptions;
|
||||
ruleArguments[1] = setTypeSymbol.ToDisplayString();
|
||||
ruleArguments[2] = serializableSetType.Rule;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableSetElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = setElementRule.RuleName,
|
||||
RuleArguments = setElementRuleArguments
|
||||
};
|
||||
|
||||
setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
Array.Copy(serializableSetType.RuleArguments, 0, ruleArguments, 3, length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{property.Name} = new System.Collections.Generic.HashSet<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableSetElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = setElementRule.RuleName,
|
||||
RuleArguments = setElementRuleArguments
|
||||
};
|
||||
|
||||
setElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableSetElement, parentReference);
|
||||
source.AppendLine($"{indent} {property.Name}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var setElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var setElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, setElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableSetElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = setElementRule.RuleName,
|
||||
RuleArguments = setElementRuleArguments
|
||||
};
|
||||
|
||||
setElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableSetElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,206 +19,207 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class KeyValuePairMigrationRule : MigrationRule
|
||||
{
|
||||
public class KeyValuePairMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(KeyValuePairMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(KeyValuePairMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation))
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsKeyValuePair(compilation))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var keySymbolType = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"key",
|
||||
keySymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var valueSymbolType = namedTypeSymbol.TypeArguments[1];
|
||||
|
||||
var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"value",
|
||||
valueSymbolType,
|
||||
1,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0;
|
||||
var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0;
|
||||
var index = 0;
|
||||
|
||||
// Key
|
||||
ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength];
|
||||
ruleArguments[index++] = ""; // Extra options
|
||||
ruleArguments[index++] = keySymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = keySerializedProperty.Rule;
|
||||
ruleArguments[index++] = keyArgumentsLength.ToString();
|
||||
if (keyArgumentsLength > 0)
|
||||
{
|
||||
Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
|
||||
index += keyArgumentsLength;
|
||||
}
|
||||
|
||||
// Value
|
||||
ruleArguments[index++] = valueSymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = valueSerializedProperty.Rule;
|
||||
|
||||
if (valueArgumentsLength > 0)
|
||||
{
|
||||
Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
var keySymbolType = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var keySerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"key",
|
||||
keySymbolType,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var valueSymbolType = namedTypeSymbol.TypeArguments[1];
|
||||
|
||||
var valueSerializedProperty = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"value",
|
||||
valueSymbolType,
|
||||
1,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var keyArgumentsLength = keySerializedProperty.RuleArguments?.Length ?? 0;
|
||||
var valueArgumentsLength = valueSerializedProperty.RuleArguments?.Length ?? 0;
|
||||
var index = 0;
|
||||
|
||||
// Key
|
||||
ruleArguments = new string[6 + keyArgumentsLength + valueArgumentsLength];
|
||||
ruleArguments[index++] = ""; // Extra options
|
||||
ruleArguments[index++] = keySymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = keySerializedProperty.Rule;
|
||||
ruleArguments[index++] = keyArgumentsLength.ToString();
|
||||
if (keyArgumentsLength > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1; // skip extra options
|
||||
var keyType = ruleArguments![index++];
|
||||
var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var serializableKeyProperty = new SerializableProperty
|
||||
{
|
||||
Name = "key",
|
||||
Type = keyType,
|
||||
Rule = keyRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableKeyProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var serializableValueProperty = new SerializableProperty
|
||||
{
|
||||
Name = "value",
|
||||
Type = valueType,
|
||||
Rule = valueRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableValueProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
source.AppendLine(
|
||||
$"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);"
|
||||
);
|
||||
Array.Copy(keySerializedProperty.RuleArguments!, 0, ruleArguments, index, keyArgumentsLength);
|
||||
index += keyArgumentsLength;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
// Value
|
||||
ruleArguments[index++] = valueSymbolType.ToDisplayString();
|
||||
ruleArguments[index++] = valueSerializedProperty.Rule;
|
||||
|
||||
if (valueArgumentsLength > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1; // skip extra options
|
||||
var keyType = ruleArguments![index++];
|
||||
var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var serializableKeyProperty = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}.Key",
|
||||
Type = keyType,
|
||||
Rule = keyRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyRule.GenerateSerializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableKeyProperty
|
||||
);
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var serializableValueProperty = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}.Value",
|
||||
Type = valueType,
|
||||
Rule = valueRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueRule.GenerateSerializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableValueProperty
|
||||
);
|
||||
Array.Copy(valueSerializedProperty.RuleArguments!, 0, ruleArguments, index, valueArgumentsLength);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1; // skip extra options
|
||||
var keyType = ruleArguments![index++];
|
||||
var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var serializableKeyProperty = new SerializableProperty
|
||||
{
|
||||
Name = "key",
|
||||
Type = keyType,
|
||||
Rule = keyRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableKeyProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var serializableValueProperty = new SerializableProperty
|
||||
{
|
||||
Name = "value",
|
||||
Type = valueType,
|
||||
Rule = valueRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueRule.GenerateDeserializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableValueProperty,
|
||||
parentReference
|
||||
);
|
||||
|
||||
source.AppendLine(
|
||||
$"{indent}{property.Name} = new {SymbolMetadata.KEYVALUEPAIR_STRUCT}<{keyType}, {valueType}>(key, value);"
|
||||
);
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var index = 1; // skip extra options
|
||||
var keyType = ruleArguments![index++];
|
||||
var keyRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var keyRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (keyRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, keyRuleArguments, 0, keyRuleArguments.Length);
|
||||
index += keyRuleArguments.Length;
|
||||
}
|
||||
|
||||
var serializableKeyProperty = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}.Key",
|
||||
Type = keyType,
|
||||
Rule = keyRule.RuleName,
|
||||
RuleArguments = keyRuleArguments
|
||||
};
|
||||
|
||||
keyRule.GenerateSerializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableKeyProperty
|
||||
);
|
||||
|
||||
var valueType = ruleArguments[index++];
|
||||
var valueRule = SerializableMigrationRulesEngine.Rules[ruleArguments[index++]];
|
||||
var valueRuleArguments = new string[int.Parse(ruleArguments[index++])];
|
||||
|
||||
if (valueRuleArguments.Length > 0)
|
||||
{
|
||||
Array.Copy(ruleArguments, index, valueRuleArguments, 0, valueRuleArguments.Length);
|
||||
}
|
||||
|
||||
var serializableValueProperty = new SerializableProperty
|
||||
{
|
||||
Name = $"{property.Name}.Value",
|
||||
Type = valueType,
|
||||
Rule = valueRule.RuleName,
|
||||
RuleArguments = valueRuleArguments
|
||||
};
|
||||
|
||||
valueRule.GenerateSerializationMethod(
|
||||
source,
|
||||
indent,
|
||||
serializableValueProperty
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,152 +20,153 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class ListMigrationRule : MigrationRule
|
||||
{
|
||||
public class ListMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(ListMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(ListMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation))
|
||||
{
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol || !symbol.IsList(compilation))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var listTypeSymbol = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ListEntry",
|
||||
listTypeSymbol,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
var length = serializableListType.RuleArguments?.Length ?? 0;
|
||||
ruleArguments = new string[length + 3];
|
||||
ruleArguments[0] = extraOptions;
|
||||
ruleArguments[1] = listTypeSymbol.ToDisplayString();
|
||||
ruleArguments[2] = serializableListType.Rule;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length);
|
||||
}
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
var listTypeSymbol = namedTypeSymbol.TypeArguments[0];
|
||||
|
||||
var serializableListType = SerializableMigrationRulesEngine.GenerateSerializableProperty(
|
||||
compilation,
|
||||
"ListEntry",
|
||||
listTypeSymbol,
|
||||
0,
|
||||
attributes,
|
||||
serializableTypes,
|
||||
embeddedSerializableTypes,
|
||||
parentSymbol,
|
||||
null
|
||||
);
|
||||
|
||||
var extraOptions = "";
|
||||
if (attributes.Any(a => a.IsTidy(compilation)))
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]];
|
||||
|
||||
var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableListElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = listElementRule.RuleName,
|
||||
RuleArguments = listElementRuleArguments
|
||||
};
|
||||
|
||||
listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference);
|
||||
source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
extraOptions += "@Tidy";
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
var length = serializableListType.RuleArguments?.Length ?? 0;
|
||||
ruleArguments = new string[length + 3];
|
||||
ruleArguments[0] = extraOptions;
|
||||
ruleArguments[1] = listTypeSymbol.ToDisplayString();
|
||||
ruleArguments[2] = serializableListType.Rule;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableListElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = listElementRule.RuleName,
|
||||
RuleArguments = listElementRuleArguments
|
||||
};
|
||||
|
||||
listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
Array.Copy(serializableListType.RuleArguments!, 0, ruleArguments, 3, length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[argumentsOffset + 1]];
|
||||
|
||||
var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyIndex = $"{propertyVarPrefix}Index";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
source.AppendLine($"{indent}{ruleArguments[argumentsOffset]} {propertyEntry};");
|
||||
source.AppendLine($"{indent}var {propertyCount} = reader.ReadEncodedInt();");
|
||||
source.AppendLine($"{indent}{propertyName} = new System.Collections.Generic.List<{ruleArguments[argumentsOffset]}>({propertyCount});");
|
||||
source.AppendLine($"{indent}for (var {propertyIndex} = 0; {propertyIndex} < {propertyCount}; {propertyIndex}++)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
|
||||
var serializableListElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = listElementRule.RuleName,
|
||||
RuleArguments = listElementRuleArguments
|
||||
};
|
||||
|
||||
listElementRule.GenerateDeserializationMethod(source, $"{indent} ", serializableListElement, parentReference);
|
||||
source.AppendLine($"{indent} {propertyName}.Add({propertyEntry});");
|
||||
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var hasExtraOptions = ruleArguments![0] == "" || ruleArguments[0].StartsWith("@", StringComparison.Ordinal);
|
||||
var shouldTidy = hasExtraOptions && ruleArguments[0].Contains("@Tidy");
|
||||
var argumentsOffset = hasExtraOptions ? 1 : 0;
|
||||
|
||||
var listElementRule = SerializableMigrationRulesEngine.Rules[ruleArguments[1 + argumentsOffset]];
|
||||
var listElementRuleArguments = new string[ruleArguments.Length - 2 - argumentsOffset];
|
||||
Array.Copy(ruleArguments, 2 + argumentsOffset, listElementRuleArguments, 0, ruleArguments.Length - 2 - argumentsOffset);
|
||||
|
||||
var propertyName = property.Name;
|
||||
var propertyVarPrefix = $"{char.ToLower(propertyName[0])}{propertyName.Substring(1, propertyName.Length - 1)}";
|
||||
var propertyEntry = $"{propertyVarPrefix}Entry";
|
||||
var propertyCount = $"{propertyVarPrefix}Count";
|
||||
|
||||
if (shouldTidy)
|
||||
{
|
||||
source.AppendLine($"{indent}{property.Name}?.Tidy();");
|
||||
}
|
||||
source.AppendLine($"{indent}var {propertyCount} = {property.Name}?.Count ?? 0;");
|
||||
source.AppendLine($"{indent}writer.WriteEncodedInt({propertyCount});");
|
||||
source.AppendLine($"{indent}if ({propertyCount} > 0)");
|
||||
source.AppendLine($"{indent}{{");
|
||||
source.AppendLine($"{indent} foreach (var {propertyEntry} in {property.Name}!)");
|
||||
source.AppendLine($"{indent} {{");
|
||||
|
||||
var serializableListElement = new SerializableProperty
|
||||
{
|
||||
Name = propertyEntry,
|
||||
Type = ruleArguments[argumentsOffset],
|
||||
Rule = listElementRule.RuleName,
|
||||
RuleArguments = listElementRuleArguments
|
||||
};
|
||||
|
||||
listElementRule.GenerateSerializationMethod(source, $"{indent} ", serializableListElement);
|
||||
|
||||
source.AppendLine($"{indent} }}");
|
||||
source.AppendLine($"{indent}}}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration;
|
||||
|
||||
public abstract class MigrationRule : ISerializableMigrationRule
|
||||
{
|
||||
public abstract string RuleName { get; }
|
||||
|
||||
public virtual void GenerateMigrationProperty(
|
||||
StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty
|
||||
)
|
||||
{
|
||||
var propertyType = serializableProperty.Type;
|
||||
var type = compilation.GetTypeByMetadataName(propertyType)?.IsValueType == true
|
||||
|| SymbolMetadata.IsPrimitiveFromTypeDisplayString(propertyType) && propertyType != "bool"
|
||||
? $"{propertyType}{(serializableProperty.UsesSaveFlag == true ? "?" : "")}" : propertyType;
|
||||
|
||||
source.AppendLine($"{indent}internal readonly {type} {serializableProperty.Name};");
|
||||
}
|
||||
|
||||
public abstract bool GenerateRuleState(
|
||||
Compilation compilation, ISymbol symbol, ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes, ISymbol? parentSymbol, out string[] ruleArguments
|
||||
);
|
||||
|
||||
public abstract void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
);
|
||||
|
||||
public abstract void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property);
|
||||
}
|
||||
|
|
@ -20,129 +20,130 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class PrimitiveTypeMigrationRule : MigrationRule
|
||||
{
|
||||
public class PrimitiveTypeMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(PrimitiveTypeMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(PrimitiveTypeMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
|
||||
{
|
||||
if (symbol.IsIpAddress(compilation) || symbol.IsTimeSpan(compilation))
|
||||
{
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
symbol is not ITypeSymbol {
|
||||
SpecialType: not (not
|
||||
SpecialType.System_Boolean and not
|
||||
SpecialType.System_SByte and not
|
||||
SpecialType.System_Int16 and not
|
||||
SpecialType.System_Int32 and not
|
||||
SpecialType.System_Int64 and not
|
||||
SpecialType.System_Byte and not
|
||||
SpecialType.System_UInt16 and not
|
||||
SpecialType.System_UInt32 and not
|
||||
SpecialType.System_UInt64 and not
|
||||
SpecialType.System_Single and not
|
||||
SpecialType.System_Double and not
|
||||
SpecialType.System_String and not
|
||||
SpecialType.System_Decimal and not
|
||||
SpecialType.System_DateTime)
|
||||
} typeSymbol
|
||||
)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = typeSymbol.SpecialType switch
|
||||
{
|
||||
SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) =>
|
||||
new[] { "EncodedInt" },
|
||||
SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) =>
|
||||
new[] { "DeltaTime" },
|
||||
SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
|
||||
new[] { "InternString" },
|
||||
_ => new[] { "" }
|
||||
};
|
||||
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
if (
|
||||
symbol is not ITypeSymbol {
|
||||
SpecialType: not (not
|
||||
SpecialType.System_Boolean and not
|
||||
SpecialType.System_SByte and not
|
||||
SpecialType.System_Int16 and not
|
||||
SpecialType.System_Int32 and not
|
||||
SpecialType.System_Int64 and not
|
||||
SpecialType.System_Byte and not
|
||||
SpecialType.System_UInt16 and not
|
||||
SpecialType.System_UInt32 and not
|
||||
SpecialType.System_UInt64 and not
|
||||
SpecialType.System_Single and not
|
||||
SpecialType.System_Double and not
|
||||
SpecialType.System_String and not
|
||||
SpecialType.System_Decimal and not
|
||||
SpecialType.System_DateTime)
|
||||
} typeSymbol
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
|
||||
|
||||
const string ipAddress = SymbolMetadata.IPADDRESS_CLASS;
|
||||
const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT;
|
||||
const string date = "System.DateTime";
|
||||
|
||||
var readMethod = property.Type switch
|
||||
{
|
||||
"bool" => "ReadBool",
|
||||
"sbyte" => "ReadSByte",
|
||||
"short" => "ReadShort",
|
||||
"int" when argument == "EncodedInt" => "ReadEncodedInt",
|
||||
"int" => "ReadInt",
|
||||
"long" => "ReadLong",
|
||||
"byte" => "ReadByte",
|
||||
"ushort" => "ReadUShort",
|
||||
"uint" => "ReadUInt",
|
||||
"ulong" => "ReadULong",
|
||||
"float" => "ReadFloat",
|
||||
"double" => "ReadDouble",
|
||||
"string" => "ReadString",
|
||||
"decimal" => "ReadDecimal",
|
||||
date when argument == "DeltaTime" => "ReadDeltaTime",
|
||||
date => "ReadDateTime",
|
||||
ipAddress => "ReadIPAddress",
|
||||
timeSpan => "ReadTimeSpan"
|
||||
};
|
||||
|
||||
var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : "";
|
||||
|
||||
source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
ruleArguments = typeSymbol.SpecialType switch
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
SpecialType.System_Int32 when attributes.Any(a => a.IsEncodedInt(compilation)) =>
|
||||
new[] { "EncodedInt" },
|
||||
SpecialType.System_DateTime when attributes.Any(a => a.IsDeltaDateTime(compilation)) =>
|
||||
new[] { "DeltaTime" },
|
||||
SpecialType.System_String when attributes.Any(a => a.IsInternString(compilation)) =>
|
||||
new[] { "InternString" },
|
||||
_ => new[] { "" }
|
||||
};
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
|
||||
return true;
|
||||
}
|
||||
|
||||
var writeMethod = property.Type switch
|
||||
{
|
||||
"System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
|
||||
"int" when argument == "EncodedInt" => "WriteEncodedInt",
|
||||
_ => "Write"
|
||||
};
|
||||
|
||||
source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
|
||||
|
||||
const string ipAddress = SymbolMetadata.IPADDRESS_CLASS;
|
||||
const string timeSpan = SymbolMetadata.TIMESPAN_STRUCT;
|
||||
const string date = "System.DateTime";
|
||||
|
||||
var readMethod = property.Type switch
|
||||
{
|
||||
"bool" => "ReadBool",
|
||||
"sbyte" => "ReadSByte",
|
||||
"short" => "ReadShort",
|
||||
"int" when argument == "EncodedInt" => "ReadEncodedInt",
|
||||
"int" => "ReadInt",
|
||||
"long" => "ReadLong",
|
||||
"byte" => "ReadByte",
|
||||
"ushort" => "ReadUShort",
|
||||
"uint" => "ReadUInt",
|
||||
"ulong" => "ReadULong",
|
||||
"float" => "ReadFloat",
|
||||
"double" => "ReadDouble",
|
||||
"string" => "ReadString",
|
||||
"decimal" => "ReadDecimal",
|
||||
date when argument == "DeltaTime" => "ReadDeltaTime",
|
||||
date => "ReadDateTime",
|
||||
ipAddress => "ReadIPAddress",
|
||||
timeSpan => "ReadTimeSpan"
|
||||
};
|
||||
|
||||
var readArgument = readMethod == "ReadString" && argument == "InternString" ? "true" : "";
|
||||
|
||||
source.AppendLine($"{indent}{propertyName} = reader.{readMethod}({readArgument});");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 ? property.RuleArguments[0] : null;
|
||||
|
||||
var writeMethod = property.Type switch
|
||||
{
|
||||
"System.DateTime" when argument == "DeltaTime" => "WriteDeltaTime",
|
||||
"int" when argument == "EncodedInt" => "WriteEncodedInt",
|
||||
_ => "Write"
|
||||
};
|
||||
|
||||
source.AppendLine($"{indent}writer.{writeMethod}({propertyName});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,61 +19,62 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class PrimitiveUOTypeMigrationRule : MigrationRule
|
||||
{
|
||||
public class PrimitiveUOTypeMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(PrimitiveUOTypeMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(PrimitiveUOTypeMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
ruleArguments = symbol switch
|
||||
{
|
||||
ruleArguments = symbol switch
|
||||
{
|
||||
_ when symbol.IsPoint2D(compilation) => new[] { "Point2D" },
|
||||
_ when symbol.IsPoint3D(compilation) => new[] { "Point3D" },
|
||||
_ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" },
|
||||
_ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" },
|
||||
_ when symbol.IsRace(compilation) => new[] { "Race" },
|
||||
_ when symbol.IsMap(compilation) => new[] { "Map" },
|
||||
_ when symbol.IsBitArray(compilation) => new[] { "BitArray" },
|
||||
_ => null
|
||||
};
|
||||
_ when symbol.IsPoint2D(compilation) => new[] { "Point2D" },
|
||||
_ when symbol.IsPoint3D(compilation) => new[] { "Point3D" },
|
||||
_ when symbol.IsRectangle2D(compilation) => new[] { "Rect2D" },
|
||||
_ when symbol.IsRectangle3D(compilation) => new[] { "Rect3D" },
|
||||
_ when symbol.IsRace(compilation) => new[] { "Race" },
|
||||
_ when symbol.IsMap(compilation) => new[] { "Map" },
|
||||
_ when symbol.IsBitArray(compilation) => new[] { "BitArray" },
|
||||
_ => null
|
||||
};
|
||||
|
||||
return ruleArguments != null;
|
||||
return ruleArguments != null;
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = reader.Read{property.RuleArguments?[0] ?? ""}();");
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
}
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,63 +19,64 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class RawSerializableMigrationRule : MigrationRule
|
||||
{
|
||||
public class RawSerializableMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(RawSerializableMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(RawSerializableMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is not ITypeSymbol typeSymbol)
|
||||
{
|
||||
if (symbol is not ITypeSymbol typeSymbol)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = new[] { "" };
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
if (!typeSymbol.HasRawSerializableInterface(compilation, embeddedSerializableTypes))
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});");
|
||||
source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = new[] { "" };
|
||||
return true;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}({parentReference ?? "this"});");
|
||||
source.AppendLine($"{indent}{propertyName}.Deserialize(reader);");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,56 +19,57 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class SerializableInterfaceMigrationRule : MigrationRule
|
||||
{
|
||||
public class SerializableInterfaceMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(SerializableInterfaceMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(SerializableInterfaceMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
|
||||
{
|
||||
if (symbol is ITypeSymbol typeSymbol && typeSymbol.HasSerializableInterface(compilation, serializableTypes))
|
||||
{
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
ruleArguments = Array.Empty<string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName} = reader.ReadEntity<{property.Type}>();");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}writer.Write({propertyName});");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,66 +19,67 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class SerializationMethodSignatureMigrationRule : MigrationRule
|
||||
{
|
||||
public class SerializationMethodSignatureMigrationRule : ISerializableMigrationRule
|
||||
public override string RuleName => nameof(SerializationMethodSignatureMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(SerializationMethodSignatureMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true)
|
||||
{
|
||||
if ((symbol as ITypeSymbol)?.HasPublicSerializeMethod(compilation, serializableTypes) != true)
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol ||
|
||||
!namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
if (symbol is not INamedTypeSymbol namedTypeSymbol ||
|
||||
!namedTypeSymbol.HasGenericReaderCtor(compilation, parentSymbol, out var requiresParent))
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 &&
|
||||
property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : "";
|
||||
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});");
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
ruleArguments = new[] { requiresParent ? "DeserializationRequiresParent" : "" };
|
||||
return true;
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var argument = property.RuleArguments?.Length >= 1 &&
|
||||
property.RuleArguments[0] == "DeserializationRequiresParent" ? ", this" : "";
|
||||
|
||||
source.AppendLine($"{indent}{propertyName} = new {property.Type}(reader{argument});");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
source.AppendLine($"{indent}{propertyName}.Serialize(writer);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,107 +20,117 @@ using System.Text;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using SerializationGenerator;
|
||||
|
||||
namespace SerializableMigration
|
||||
namespace SerializableMigration;
|
||||
|
||||
public class TimerMigrationRule : MigrationRule, IPostDeserializeMethod
|
||||
{
|
||||
public class TimerMigrationRule : ISerializableMigrationRule, IPostDeserializeMethod
|
||||
public override string RuleName => nameof(TimerMigrationRule);
|
||||
|
||||
public override bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
{
|
||||
public string RuleName => nameof(TimerMigrationRule);
|
||||
|
||||
public bool GenerateRuleState(
|
||||
Compilation compilation,
|
||||
ISymbol symbol,
|
||||
ImmutableArray<AttributeData> attributes,
|
||||
ImmutableArray<INamedTypeSymbol> serializableTypes,
|
||||
ImmutableArray<INamedTypeSymbol> embeddedSerializableTypes,
|
||||
ISymbol? parentSymbol,
|
||||
out string[] ruleArguments
|
||||
)
|
||||
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
|
||||
{
|
||||
if (!(symbol is ITypeSymbol typeSymbol && typeSymbol.IsTimer(compilation)))
|
||||
{
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
|
||||
? new[] { "@TimerDrift" }
|
||||
: new[] { "" };
|
||||
|
||||
return true;
|
||||
ruleArguments = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GenerateDeserializationMethod(StringBuilder source, string indent, SerializableProperty property, string? parentReference)
|
||||
ruleArguments = attributes.Any(a => a.IsTimerDrift(compilation))
|
||||
? new[] { "@TimerDrift" }
|
||||
: new[] { "" };
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GenerateMigrationProperty(
|
||||
StringBuilder source, Compilation compilation, string indent, SerializableProperty serializableProperty
|
||||
)
|
||||
{
|
||||
source.AppendLine($"{indent}internal readonly System.DateTime {serializableProperty.Name}Next;");
|
||||
source.AppendLine($"{indent}internal readonly System.TimeSpan {serializableProperty.Name}Delay;");
|
||||
}
|
||||
|
||||
public override void GenerateDeserializationMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, string? parentReference, bool isMigration = false
|
||||
)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments![0].Contains("@TimerDrift");
|
||||
|
||||
var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
|
||||
source.AppendLine($"{indent}var {propertyName}Next = {readTimer};");
|
||||
source.AppendLine($"{indent}var {propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments![0].Contains("@TimerDrift");
|
||||
|
||||
var readTimer = driftTimer ? "reader.ReadDeltaTime()" : "reader.ReadDateTime()";
|
||||
var useVar = isMigration ? "" : "var ";
|
||||
source.AppendLine($"{indent}{useVar}{propertyName}Next = {readTimer};");
|
||||
source.AppendLine($"{indent}{useVar}{propertyName}Delay = {propertyName}Next == System.DateTime.MinValue ? System.TimeSpan.MinValue : {propertyName}Next - Core.Now;");
|
||||
}
|
||||
|
||||
public override void GenerateSerializationMethod(StringBuilder source, string indent, SerializableProperty property)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
var expectedRule = RuleName;
|
||||
var ruleName = property.Rule;
|
||||
if (expectedRule != ruleName)
|
||||
{
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments![0].Contains("@TimerDrift");
|
||||
|
||||
var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
|
||||
source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);");
|
||||
throw new ArgumentException($"Invalid rule applied to property {ruleName}. Expecting {expectedRule}, but received {ruleName}.");
|
||||
}
|
||||
|
||||
public void PostDeserializeMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
|
||||
)
|
||||
{
|
||||
var deserializeTimerMethod = classSymbol
|
||||
.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(
|
||||
m =>
|
||||
var propertyName = property.Name;
|
||||
var ruleArguments = property.RuleArguments;
|
||||
var driftTimer = ruleArguments![0].Contains("@TimerDrift");
|
||||
|
||||
var writerMethod = driftTimer ? "WriteDeltaTime" : "Write";
|
||||
source.AppendLine($"{indent}writer.{writerMethod}({propertyName}?.Next ?? System.DateTime.MinValue);");
|
||||
}
|
||||
|
||||
public void PostDeserializeMethod(
|
||||
StringBuilder source, string indent, SerializableProperty property, Compilation compilation, INamedTypeSymbol classSymbol
|
||||
)
|
||||
{
|
||||
var deserializeTimerMethod = classSymbol
|
||||
.GetMembers()
|
||||
.OfType<IMethodSymbol>()
|
||||
.FirstOrDefault(
|
||||
m =>
|
||||
{
|
||||
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
|
||||
{
|
||||
if (!m.ReturnsVoid || m.Parameters.Length != 1 || !m.Parameters[0].Type.IsTimeSpan(compilation))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return m.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
attr =>
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(
|
||||
return m.GetAttributes()
|
||||
.FirstOrDefault(
|
||||
attr =>
|
||||
{
|
||||
if (!SymbolEqualityComparer.Default.Equals(
|
||||
attr.AttributeClass,
|
||||
compilation.GetTypeByMetadataName(
|
||||
SymbolMetadata.DESERIALIZE_TIMER_FIELD_ATTRIBUTE
|
||||
)
|
||||
))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var order = (int)attr.ConstructorArguments[0].Value!;
|
||||
return order == property.Order;
|
||||
{
|
||||
return false;
|
||||
}
|
||||
) != null;
|
||||
}
|
||||
) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
|
||||
|
||||
source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
|
||||
}
|
||||
var order = (int)attr.ConstructorArguments[0].Value!;
|
||||
return order == property.Order;
|
||||
}
|
||||
) != null;
|
||||
}
|
||||
) ?? throw new Exception("Serializing a timer requires a method with the DeserializeTimerField attribute to handle creating the timer itself.");
|
||||
|
||||
source.AppendLine($"{indent}{deserializeTimerMethod.Name}({property.Name}Delay);");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue