This commit is contained in:
Christian Köllner 2020-01-19 14:35:43 +01:00
parent 5b8f6722ec
commit 4da57f9a28
12 changed files with 147 additions and 97 deletions

View File

@ -10,8 +10,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.3.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.3.1" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.4.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="3.4.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Mono.Cecil" Version="0.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="1.4.0" />

View File

@ -61,7 +61,7 @@
{
var topDecl = ClassDeclaration(_names.MakeTypeName(def).Identifier)
.AddModifiers(Public)
.AddBaseListTypes(SimpleBaseType(Type<Capnp.ICapnpSerializable>()));
.AddBaseListTypes(SimpleBaseType(_names.Type<Capnp.ICapnpSerializable>(true)));
if (def.GenericParameters.Count > 0)
{

View File

@ -22,7 +22,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
var whichEnum = EnumDeclaration(_names.UnionDiscriminatorEnum.ToString())
.AddModifiers(Public)
.AddBaseListTypes(SimpleBaseType(Type<ushort>()));
.AddBaseListTypes(SimpleBaseType(_names.Type<ushort>()));
var discFields = def.Fields.Where(f => f.DiscValue.HasValue);
@ -52,7 +52,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
var decl = EnumDeclaration(def.Name)
.WithAttributeLists(MakeTypeIdAttributeLists(def.Id))
.AddModifiers(Public)
.AddBaseListTypes(SimpleBaseType(Type<ushort>()));
.AddBaseListTypes(SimpleBaseType(_names.Type<ushort>()));
foreach (var enumerant in def.Enumerants.OrderBy(e => e.CodeOrder))
{

View File

@ -75,7 +75,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
return null;
}
var prop = PropertyDeclaration(_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.DomainClass),
var prop = PropertyDeclaration(_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.DomainClassNullable),
_names.GetCodeIdentifier(field).Identifier)
.AddModifiers(Public).AddAccessorListAccessors(
AccessorDeclaration(SyntaxKind.GetAccessorDeclaration)
@ -111,7 +111,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
MemberDeclarationSyntax MakeUnionContentField()
{
return FieldDeclaration(
VariableDeclaration(SyntaxHelpers.Type<object>())
VariableDeclaration(_names.Type<object>())
.WithVariables(
SingletonSeparatedList<VariableDeclaratorSyntax>(
VariableDeclarator(_names.UnionContentField.Identifier))))
@ -282,7 +282,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
value.Decode();
return ArrayCreationExpression(ArrayType(
_names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClass))
_names.MakeTypeSyntax(value.Type.ElementType, scope, TypeUsage.DomainClassNullable))
.WithRankSpecifiers(
SingletonList<ArrayRankSpecifierSyntax>(
ArrayRankSpecifier(
@ -611,7 +611,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(nameof(Capnp.CapnpSerializable)),
GenericName(nameof(Capnp.CapnpSerializable.Create))
.AddTypeArgumentListArguments(elementType)))
.AddTypeArgumentListArguments(MakeNonNullableType(elementType))))
.AddArgumentListArguments(Argument(IdentifierName("_"))))));
}
@ -645,7 +645,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
.AddArgumentListArguments(Argument(
SimpleLambdaExpression(
Parameter(Identifier("_")),
CastExpression(Type<object>(), IdentifierName("_")))));
CastExpression(_names.Type<object>(), IdentifierName("_")))));
}
ExpressionSyntax MakeDeserializeMethodRightHandSide(Field field)
@ -662,10 +662,10 @@ namespace CapnpC.CSharp.Generator.CodeGen
IdentifierName(nameof(Capnp.CapnpSerializable)),
GenericName(nameof(Capnp.CapnpSerializable.Create))
.AddTypeArgumentListArguments(
_names.MakeTypeSyntax(
MakeNonNullableType(_names.MakeTypeSyntax(
field.Type,
field.DeclaringType,
TypeUsage.DomainClass))))
TypeUsage.DomainClass)))))
.AddArgumentListArguments(Argument(MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
_names.ReaderParameter.IdentifierName,
@ -684,7 +684,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SyntaxKind.SimpleMemberAccessExpression,
_names.ReaderParameter.IdentifierName,
_names.GetCodeIdentifier(field).IdentifierName),
_names.MakeTypeSyntax(elementType, field.DeclaringType, TypeUsage.DomainClass),
_names.MakeTypeSyntax(elementType, field.DeclaringType, TypeUsage.DomainClassNullable),
rank);
case TypeTag.ListPointer:
@ -849,7 +849,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
ExplicitInterfaceSpecifier(IdentifierName(nameof(Capnp.ICapnpSerializable))))
.AddParameterListParameters(
Parameter(_names.AnonymousParameter.Identifier)
.WithType(Type<Capnp.SerializerState>()))
.WithType(_names.Type<Capnp.SerializerState>(true)))
.AddBodyStatements(
ExpressionStatement(
InvocationExpression(_names.SerializeMethod.IdentifierName)
@ -933,7 +933,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
ExplicitInterfaceSpecifier(IdentifierName(nameof(Capnp.ICapnpSerializable))))
.AddParameterListParameters(
Parameter(_names.AnonymousParameter.Identifier)
.WithType(Type<Capnp.DeserializerState>()))
.WithType(_names.Type<Capnp.DeserializerState>()))
.AddBodyStatements(stmts.ToArray());
}

View File

@ -66,6 +66,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
public string PipeliningExtensionsClassFormat { get; }
public string ProxyClassFormat { get; }
public string SkeletonClassFormat { get; }
public bool NullableEnable { get; set; }
public GenNames(GeneratorOptions options)
{
TopNamespace = new Name(options.TopNamespaceName).IdentifierName;
@ -288,14 +289,14 @@ namespace CapnpC.CSharp.Generator.CodeGen
case TypeTag.AnyPointer:
case TypeTag.StructPointer:
case TypeTag.ListPointer:
return SyntaxHelpers.Type<Capnp.ListOfPointersSerializer<Capnp.DynamicSerializerState>>();
return Type<Capnp.ListOfPointersSerializer<Capnp.DynamicSerializerState>>(true);
case TypeTag.CapabilityPointer:
return SyntaxHelpers.Type<Capnp.ListOfCapsSerializer<Capnp.Rpc.BareProxy>>();
return Type<Capnp.ListOfCapsSerializer<Capnp.Rpc.BareProxy>>(true);
case TypeTag.Data:
return SyntaxHelpers.Type<Capnp.ListOfPointersSerializer<
Capnp.ListOfPrimitivesSerializer<byte>>>();
return Type<Capnp.ListOfPointersSerializer<
Capnp.ListOfPrimitivesSerializer<byte>>>(true);
case TypeTag.Enum:
return GenericName("ListOfPrimitivesSerializer")
@ -315,44 +316,44 @@ namespace CapnpC.CSharp.Generator.CodeGen
.AddTypeArgumentListArguments(MakeTypeSyntax(elementType, scope, TypeUsage.Writer));
case TypeTag.Text:
return SyntaxHelpers.Type<Capnp.ListOfTextSerializer>();
return Type<Capnp.ListOfTextSerializer>(true);
case TypeTag.Void:
return SyntaxHelpers.Type<Capnp.ListOfEmptySerializer>();
return Type<Capnp.ListOfEmptySerializer>(true);
case TypeTag.Bool:
return SyntaxHelpers.Type<Capnp.ListOfBitsSerializer>();
return Type<Capnp.ListOfBitsSerializer>(true);
case TypeTag.F32:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<float>>();
return Type<Capnp.ListOfPrimitivesSerializer<float>>(true);
case TypeTag.F64:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<double>>();
return Type<Capnp.ListOfPrimitivesSerializer<double>>(true);
case TypeTag.S8:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<sbyte>>();
return Type<Capnp.ListOfPrimitivesSerializer<sbyte>>(true);
case TypeTag.U8:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<byte>>();
return Type<Capnp.ListOfPrimitivesSerializer<byte>>(true);
case TypeTag.S16:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<short>>();
return Type<Capnp.ListOfPrimitivesSerializer<short>>(true);
case TypeTag.U16:
case TypeTag.AnyEnum:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<ushort>>();
return Type<Capnp.ListOfPrimitivesSerializer<ushort>>(true);
case TypeTag.S32:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<int>>();
return Type<Capnp.ListOfPrimitivesSerializer<int>>(true);
case TypeTag.U32:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<uint>>();
return Type<Capnp.ListOfPrimitivesSerializer<uint>>(true);
case TypeTag.S64:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<long>>();
return Type<Capnp.ListOfPrimitivesSerializer<long>>(true);
case TypeTag.U64:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<ulong>>();
return Type<Capnp.ListOfPrimitivesSerializer<ulong>>(true);
default:
throw new NotImplementedException("Unexpected type tag, don't know how to deal with this");
@ -373,19 +374,22 @@ namespace CapnpC.CSharp.Generator.CodeGen
public TypeSyntax MakeTypeSyntax(Model.Type type, TypeDefinition scope, TypeUsage usage)
{
bool nonNullable = usage != TypeUsage.DomainClassNullable;
switch (type.Tag)
{
case TypeTag.AnyEnum:
return MaybeNullableValueType(SyntaxHelpers.Type<ushort>(), usage);
return MaybeNullableValueType(Type<ushort>(), usage);
case TypeTag.CapabilityPointer:
if (type.Parameter != null)
{
return GetQName(type, scope);
return nonNullable ? GetQName(type, scope) :
MakeNullableType(GetQName(type, scope));
}
else
{
return SyntaxHelpers.Type<Capnp.Rpc.BareProxy>();
return Type<Capnp.Rpc.BareProxy>(nonNullable);
}
case TypeTag.AnyPointer:
@ -393,20 +397,22 @@ namespace CapnpC.CSharp.Generator.CodeGen
switch (usage)
{
case TypeUsage.Reader:
return SyntaxHelpers.Type<Capnp.DeserializerState>();
return Type<Capnp.DeserializerState>();
case TypeUsage.Writer:
return SyntaxHelpers.Type<Capnp.DynamicSerializerState>();
return Type<Capnp.DynamicSerializerState>();
case TypeUsage.DomainClass:
case TypeUsage.DomainClassNullable:
if (type.Parameter != null)
{
return GetQName(type, scope);
return nonNullable ?
GetQName(type, scope) :
MakeNullableType(GetQName(type, scope));
}
else
{
return SyntaxHelpers.Type<object>();
return Type<object>(nonNullable);
}
default:
@ -414,7 +420,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
}
case TypeTag.Bool:
return MaybeNullableValueType(SyntaxHelpers.Type<bool>(), usage);
return MaybeNullableValueType(Type<bool>(), usage);
case TypeTag.Data:
switch (usage)
@ -422,10 +428,10 @@ namespace CapnpC.CSharp.Generator.CodeGen
case TypeUsage.Reader:
case TypeUsage.DomainClass:
case TypeUsage.DomainClassNullable:
return SyntaxHelpers.Type<IReadOnlyList<byte>>();
return Type<IReadOnlyList<byte>>(nonNullable);
case TypeUsage.Writer:
return SyntaxHelpers.Type<Capnp.ListOfPrimitivesSerializer<byte>>();
return Type<Capnp.ListOfPrimitivesSerializer<byte>>(true);
default:
throw new NotImplementedException();
@ -448,21 +454,23 @@ namespace CapnpC.CSharp.Generator.CodeGen
return QualifiedName(GetQName(type, scope), ReaderStruct.IdentifierName);
case TypeUsage.DomainClass:
case TypeUsage.DomainClassNullable:
return GetQName(type, scope);
case TypeUsage.DomainClassNullable:
return MakeNullableType(GetQName(type, scope));
default:
throw new NotImplementedException();
}
case TypeTag.F32:
return MaybeNullableValueType(SyntaxHelpers.Type<float>(), usage);
return MaybeNullableValueType(Type<float>(), usage);
case TypeTag.F64:
return MaybeNullableValueType(SyntaxHelpers.Type<double>(), usage);
return MaybeNullableValueType(Type<double>(), usage);
case TypeTag.List when type.ElementType.Tag == TypeTag.Void && usage != TypeUsage.Writer:
return MaybeNullableValueType(SyntaxHelpers.Type<int>(), usage);
return MaybeNullableValueType(Type<int>(), usage);
case TypeTag.List:
switch (usage)
@ -477,7 +485,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
case TypeUsage.DomainClass:
case TypeUsage.DomainClassNullable:
return GenericName(Identifier("IReadOnlyList"))
.AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, TypeUsage.DomainClass));
.AddTypeArgumentListArguments(MakeTypeSyntax(type.ElementType, scope, usage));
default:
throw new NotImplementedException();
@ -487,45 +495,47 @@ namespace CapnpC.CSharp.Generator.CodeGen
switch (usage)
{
case TypeUsage.Writer:
return SyntaxHelpers.Type<Capnp.SerializerState>();
return Type<Capnp.SerializerState>();
case TypeUsage.Reader:
return SyntaxHelpers.Type<IReadOnlyList<Capnp.DeserializerState>>();
return Type<IReadOnlyList<Capnp.DeserializerState>>();
case TypeUsage.DomainClass:
return Type<IReadOnlyList<object>>(false);
case TypeUsage.DomainClassNullable:
return SyntaxHelpers.Type<IReadOnlyList<object>>();
return Type<IReadOnlyList<object>>(true);
default:
throw new NotImplementedException();
}
case TypeTag.S16:
return MaybeNullableValueType(SyntaxHelpers.Type<short>(), usage);
return MaybeNullableValueType(Type<short>(), usage);
case TypeTag.S32:
return MaybeNullableValueType(SyntaxHelpers.Type<int>(), usage);
return MaybeNullableValueType(Type<int>(), usage);
case TypeTag.S64:
return MaybeNullableValueType(SyntaxHelpers.Type<long>(), usage);
return MaybeNullableValueType(Type<long>(), usage);
case TypeTag.S8:
return MaybeNullableValueType(SyntaxHelpers.Type<sbyte>(), usage);
return MaybeNullableValueType(Type<sbyte>(), usage);
case TypeTag.Text:
return SyntaxHelpers.Type<string>();
return Type<string>(nonNullable);
case TypeTag.U16:
return MaybeNullableValueType(SyntaxHelpers.Type<ushort>(), usage);
return MaybeNullableValueType(Type<ushort>(), usage);
case TypeTag.U32:
return MaybeNullableValueType(SyntaxHelpers.Type<uint>(), usage);
return MaybeNullableValueType(Type<uint>(), usage);
case TypeTag.U64:
return MaybeNullableValueType(SyntaxHelpers.Type<ulong>(), usage);
return MaybeNullableValueType(Type<ulong>(), usage);
case TypeTag.U8:
return MaybeNullableValueType(SyntaxHelpers.Type<byte>(), usage);
return MaybeNullableValueType(Type<byte>(), usage);
case TypeTag.Void:
return PredefinedType(Token(SyntaxKind.VoidKeyword));
@ -637,5 +647,22 @@ namespace CapnpC.CSharp.Generator.CodeGen
method.Name,
MakePipeliningSupportExtensionMethodName(path)));
}
public TypeSyntax MakeNullableType(TypeSyntax type)
{
return NullableEnable ?
NullableType(type) :
type;
}
public TypeSyntax Type<T>(bool nonNullable = false)
{
return NullableEnable && !typeof(T).IsValueType && !nonNullable ?
NullableType(SyntaxHelpers.NonNullableType<T>()) :
SyntaxHelpers.NonNullableType<T>();
}
public ClassOrStructConstraintSyntax MakeNullableClassConstraint() => ClassOrStructConstraint(SyntaxKind.ClassConstraint);
}
}

View File

@ -29,13 +29,13 @@ namespace CapnpC.CSharp.Generator.CodeGen
case 1:
return GenericName(nameof(Task)).AddTypeArgumentListArguments(
_names.MakeTypeSyntax(method.Results[0].Type, method.DeclaringInterface, TypeUsage.DomainClass));
_names.MakeTypeSyntax(method.Results[0].Type, method.DeclaringInterface, TypeUsage.DomainClassNullable));
default:
return GenericName(nameof(Task)).AddTypeArgumentListArguments(
TupleType(SeparatedList(
method.Results.Select(
f => TupleElement(_names.MakeTypeSyntax(f.Type, method.DeclaringInterface, TypeUsage.DomainClass))))));
f => TupleElement(_names.MakeTypeSyntax(f.Type, method.DeclaringInterface, TypeUsage.DomainClassNullable))))));
}
}
@ -50,14 +50,14 @@ namespace CapnpC.CSharp.Generator.CodeGen
if (arg0.Name == null)
{
list.Add(Parameter(_names.AnonymousParameter.Identifier)
.WithType(_names.MakeTypeSyntax(arg0.Type, method.DeclaringInterface, TypeUsage.DomainClass)));
.WithType(_names.MakeTypeSyntax(arg0.Type, method.DeclaringInterface, TypeUsage.DomainClassNullable)));
}
else
{
foreach (var arg in method.Params)
{
list.Add(Parameter(Identifier(IdentifierRenamer.ToNonKeyword(arg.Name)))
.WithType(_names.MakeTypeSyntax(arg.Type, method.DeclaringInterface, TypeUsage.DomainClass)));
.WithType(_names.MakeTypeSyntax(arg.Type, method.DeclaringInterface, TypeUsage.DomainClassNullable)));
}
}
}
@ -85,7 +85,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
yield return TypeParameterConstraintClause(
_names.GetGenericTypeParameter(name).IdentifierName)
.AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint));
.AddConstraints(_names.MakeNullableClassConstraint());
}
}
@ -233,7 +233,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(nameof(Capnp.CapnpSerializable)),
GenericName(nameof(Capnp.CapnpSerializable.Create))
.AddTypeArgumentListArguments(domainType)))
.AddTypeArgumentListArguments(MakeNonNullableType(domainType))))
.AddArgumentListArguments(
Argument(_names.DeserializerLocal.IdentifierName));
@ -262,7 +262,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
yield return TypeParameterConstraintClause(
_names.GetGenericTypeParameter(name).IdentifierName)
.AddConstraints(ClassOrStructConstraint(SyntaxKind.ClassConstraint));
.AddConstraints(_names.MakeNullableClassConstraint());
}
}
@ -271,7 +271,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
var classDecl = ClassDeclaration(_names.MakeTypeName(type, NameUsage.Proxy).Identifier)
.AddModifiers(Public)
.AddBaseListTypes(
SimpleBaseType(Type<Capnp.Rpc.Proxy>()),
SimpleBaseType(_names.Type<Capnp.Rpc.Proxy>(true)),
SimpleBaseType(_names.MakeGenericTypeName(type, NameUsage.Interface)));
if (type.GenericParameters.Count > 0)
@ -361,7 +361,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SyntaxKind.SimpleMemberAccessExpression,
_names.ParamsLocal.IdentifierName,
GenericName(nameof(Capnp.SerializerState.Rewrap))
.AddTypeArgumentListArguments(Type<Capnp.DynamicSerializerState>())))
.AddTypeArgumentListArguments(_names.Type<Capnp.DynamicSerializerState>())))
.AddArgumentListArguments()),
Argument(
LiteralExpression(SyntaxKind.FalseLiteralExpression)),
@ -446,7 +446,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
GenericName(_names.GetCodeIdentifier(method).ToString())
.AddTypeArgumentListArguments(
Enumerable.Repeat(
Type<Capnp.AnyPointer>(),
_names.Type<Capnp.AnyPointer>(),
method.GenericParameters.Count).ToArray()));
}
else
@ -582,7 +582,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(nameof(Capnp.CapnpSerializable)),
GenericName(nameof(Capnp.CapnpSerializable.Create))
.AddTypeArgumentListArguments(domainType)))
.AddTypeArgumentListArguments(MakeNonNullableType(domainType))))
.AddArgumentListArguments(
Argument(_names.DeserializerLocal.IdentifierName));
@ -662,13 +662,13 @@ namespace CapnpC.CSharp.Generator.CodeGen
foreach (var method in def.Methods)
{
var methodDecl = MethodDeclaration(
Type<Task<Capnp.Rpc.AnswerOrCounterquestion>>(),
_names.Type<Task<Capnp.Rpc.AnswerOrCounterquestion>>(),
_names.GetCodeIdentifier(method).Identifier)
.AddParameterListParameters(
Parameter(_names.DeserializerLocal.Identifier)
.WithType(Type<Capnp.DeserializerState>()),
.WithType(_names.Type<Capnp.DeserializerState>()),
Parameter(_names.CancellationTokenParameter.Identifier)
.WithType(Type<CancellationToken>()))
.WithType(_names.Type<CancellationToken>()))
.AddBodyStatements(
MakeSkeletonMethodBody(method).ToArray());
@ -709,7 +709,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
.AddArgumentListArguments(
MakeSkeletonSetMethodTableArguments(type).ToArray()))),
// InterfaceId
PropertyDeclaration(Type<ulong>(), nameof(Capnp.Rpc.Skeleton<object>.InterfaceId))
PropertyDeclaration(_names.Type<ulong>(), nameof(Capnp.Rpc.Skeleton<object>.InterfaceId))
.AddModifiers(Public, Override)
.WithExpressionBody(
ArrowExpressionClause(

View File

@ -57,7 +57,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
ParameterList(
SingletonSeparatedList<ParameterSyntax>(
Parameter(_names.ReaderContextField.Identifier)
.WithType(Type<Capnp.DeserializerState>()))))
.WithType(_names.Type<Capnp.DeserializerState>()))))
.WithExpressionBody(
ArrowExpressionClause(
ObjectCreationExpression(_names.ReaderStruct.IdentifierName)
@ -78,7 +78,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
SingletonSeparatedList(
Parameter(_names.ContextParameter.Identifier)
.WithType(
Type<Capnp.DeserializerState>()))))
_names.Type<Capnp.DeserializerState>()))))
.WithExpressionBody(
ArrowExpressionClause(
ObjectCreationExpression(_names.ReaderStruct.IdentifierName)
@ -90,7 +90,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
yield return FieldDeclaration(
VariableDeclaration(
Type<Capnp.DeserializerState>())
_names.Type<Capnp.DeserializerState>())
.AddVariables(_names.ReaderContextField.VariableDeclarator))
.AddModifiers(Readonly);
@ -100,7 +100,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
ParameterList(
SingletonSeparatedList(
Parameter(_names.ContextParameter.Identifier)
.WithType(Type<Capnp.DeserializerState>()))))
.WithType(_names.Type<Capnp.DeserializerState>()))))
.WithBody(
Block(
SingletonList<StatementSyntax>(
@ -122,7 +122,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
yield return FieldDeclaration(
VariableDeclaration(
Type<Capnp.DeserializerState>())
_names.Type<Capnp.DeserializerState>())
.AddVariables(_names.ReaderContextField.VariableDeclarator))
.AddModifiers(Readonly);
@ -131,7 +131,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
.WithParameterList(
ParameterList(
SingletonSeparatedList(Parameter(_names.GroupReaderContextArg.Identifier)
.WithType(Type<Capnp.DeserializerState>()))))
.WithType(_names.Type<Capnp.DeserializerState>()))))
.WithBody(
Block(
SingletonList<StatementSyntax>(
@ -261,7 +261,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
PropertyDeclarationSyntax MakeReadPrimitiveProperty<T>(Field field, string readName)
{
return MakeReadProperty(Type<T>(), _names.GetCodeIdentifier(field).ToString(), readName, field.BitOffset.Value,
return MakeReadProperty(_names.Type<T>(), _names.GetCodeIdentifier(field).ToString(), readName, field.BitOffset.Value,
ValueOf(field.DefaultValue.ScalarValue), null, field.DiscValue.HasValue);
}
@ -278,7 +278,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
PropertyDeclarationSyntax MakeReadTextProperty(Field field)
{
return MakeReadProperty(Type<string>(), _names.GetCodeIdentifier(field).ToString(),
return MakeReadProperty(_names.Type<string>(), _names.GetCodeIdentifier(field).ToString(),
nameof(Capnp.DeserializerState.ReadText), (int)field.Offset,
ValueOf(field.DefaultValue.ScalarValue), null, field.DiscValue.HasValue);
}
@ -396,7 +396,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
case TypeTag.ListPointer:
{
listType = Type<IReadOnlyList<object>>();
listType = _names.Type<IReadOnlyList<object>>();
context = InvocationExpression(MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
@ -445,14 +445,14 @@ namespace CapnpC.CSharp.Generator.CodeGen
case TypeTag.AnyPointer:
case TypeTag.StructPointer:
{
listType = Type<IReadOnlyList<Capnp.DeserializerState>>();
listType = _names.Type<IReadOnlyList<Capnp.DeserializerState>>();
impl = context;
return;
}
case TypeTag.Void:
{
listType = Type<int>();
listType = _names.Type<int>();
impl = MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
context,

View File

@ -21,7 +21,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
public static readonly SyntaxToken Partial = Token(SyntaxKind.PartialKeyword);
public static readonly SyntaxToken This = Token(SyntaxKind.ThisKeyword);
public static TypeSyntax Type(Type type)
public static TypeSyntax NonNullableType(Type type)
{
switch (0)
{
@ -66,14 +66,14 @@ namespace CapnpC.CSharp.Generator.CodeGen
case 0 when type.IsGenericType:
return GenericName(type.Name.Substring(0, type.Name.IndexOf('`')))
.AddTypeArgumentListArguments(type.GetGenericArguments().Select(Type).ToArray());
.AddTypeArgumentListArguments(type.GetGenericArguments().Select(NonNullableType).ToArray());
default:
return ParseTypeName(type.Name);
}
}
public static TypeSyntax Type<T>() => Type(typeof(T));
public static TypeSyntax NonNullableType<T>() => NonNullableType(typeof(T));
public static ExpressionSyntax ValueOf(object value)
{
@ -83,16 +83,16 @@ namespace CapnpC.CSharp.Generator.CodeGen
return LiteralExpression(x ? SyntaxKind.TrueLiteralExpression : SyntaxKind.FalseLiteralExpression);
case sbyte x:
return CastExpression(Type<sbyte>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
return CastExpression(NonNullableType<sbyte>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
case byte x:
return CastExpression(Type<byte>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
return CastExpression(NonNullableType<byte>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
case short x:
return CastExpression(Type<short>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
return CastExpression(NonNullableType<short>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
case ushort x:
return CastExpression(Type<ushort>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
return CastExpression(NonNullableType<ushort>(), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x)));
case int x:
return LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(x));
@ -122,5 +122,14 @@ namespace CapnpC.CSharp.Generator.CodeGen
throw new NotImplementedException();
}
}
public static TypeSyntax MakeNonNullableType(TypeSyntax type)
{
if (type is NullableTypeSyntax nts)
{
type = nts.ElementType;
}
return type;
}
}
}

View File

@ -195,7 +195,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
PropertyDeclarationSyntax MakePrimitiveProperty<T>(Field field, string readName)
{
return MakeProperty(Type<T>(), null, _names.GetCodeIdentifier(field).ToString(),
return MakeProperty(_names.Type<T>(), null, _names.GetCodeIdentifier(field).ToString(),
readName,
nameof(Capnp.SerializerExtensions.WriteData),
field.BitOffset.Value,
@ -207,7 +207,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
PropertyDeclarationSyntax MakeEnumProperty(Field field, string readName)
{
return MakeProperty(_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.NotRelevant), Type<ushort>(),
return MakeProperty(_names.MakeTypeSyntax(field.Type, field.DeclaringType, TypeUsage.NotRelevant), _names.Type<ushort>(),
_names.GetCodeIdentifier(field).ToString(),
readName,
nameof(Capnp.SerializerExtensions.WriteData),
@ -220,7 +220,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
PropertyDeclarationSyntax MakeTextProperty(Field field)
{
return MakeProperty(Type<string>(), null,
return MakeProperty(_names.Type<string>(), null,
_names.GetCodeIdentifier(field).ToString(),
nameof(Capnp.SerializerState.ReadText),
nameof(Capnp.SerializerState.WriteText),
@ -282,7 +282,7 @@ namespace CapnpC.CSharp.Generator.CodeGen
{
return MakeProperty(
_names.UnionDiscriminatorEnum.IdentifierName,
Type<ushort>(),
_names.Type<ushort>(),
_names.UnionDiscriminatorProp.ToString(),
nameof(Capnp.SerializerExtensions.ReadDataUShort),
nameof(Capnp.SerializerExtensions.WriteData),

View File

@ -11,6 +11,7 @@ namespace CapnpC.CSharp.Generator.Model
public string Name { get; set; }
public string[] Namespace { get; set; }
public bool NullableEnable { get; set; } = true;
public IEnumerable<TypeDefinition> NestedTypes { get => this.GetNestedTypes(); }
public ICollection<IDefinition> NestedDefinitions { get; } = new List<IDefinition>();

View File

@ -2,7 +2,9 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>8.0</LangVersion>
<Nullable>Enable</Nullable>
<Version>1.3-local</Version>
<Configurations>Debug;Release</Configurations>
<PackageReferenceVersion Condition="'$(PackageReferenceVersion)'==''">$(Version)*</PackageReferenceVersion>

11
include/csharp.capnp Normal file
View File

@ -0,0 +1,11 @@
@0xeb0d831668c6edab;
$csNamespace("Capnp.Annotations");
annotation csNamespace @0xeb0d831668c6eda0 (file) : Text;
# C# namespace for code generation
annotation csNullableEnable @0xeb0d831668c6eda1 (file) : Bool;
# Whether to generate C# nullable reference types
annotation csName @0xeb0d831668c6eda2 (field, enumerant, struct, enum, interface, method, param, group, union) : Text;
# C# member name for code generation