protected void AddConstructorAssignedField( TypeReferenceBuilder type, string fieldName, ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, bool skipNullCheck = false) { var paramName = fieldName.TrimStart('_'); classBuilder.AddField() .SetReadOnly() .SetName(fieldName) .SetType(type); AssignmentBuilder assignment = AssignmentBuilder .New() .SetLefthandSide(fieldName) .SetRighthandSide(paramName); if (!skipNullCheck) { assignment.AssertNonNull(); } constructorBuilder .AddCode(assignment) .AddParameter(paramName, b => b.SetType(type)); }
private static void AddInjectedSerializers( OperationDescriptor descriptor, ConstructorBuilder constructorBuilder, ClassBuilder classBuilder) { var neededSerializers = descriptor .Arguments .GroupBy(x => x.Type.Name) .ToDictionary(x => x.Key, x => x.First()); if (!neededSerializers.Any()) { return; } constructorBuilder .AddParameter(_serializerResolver) .SetType(TypeNames.ISerializerResolver); foreach (var property in neededSerializers.Values) { if (property.Type.GetName().Value is { } name) { var fieldName = $"{GetFieldName(name)}Formatter"; constructorBuilder .AddCode( AssignmentBuilder .New() .SetLefthandSide(fieldName) .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName( _serializerResolver, "GetInputValueFormatter") .AddArgument(name.AsStringToken()))); classBuilder .AddField() .SetName(fieldName) .SetAccessModifier(AccessModifier.Private) .SetType(TypeNames.IInputValueFormatter) .SetReadOnly(); }
protected override void Generate(ITypeDescriptor typeDescriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { ComplexTypeDescriptor complexTypeDescriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result entity mapper can only be generated for complex types"); var className = CreateResultInfoName(complexTypeDescriptor.RuntimeType.Name); fileName = className; path = State; ns = CreateStateNamespace(complexTypeDescriptor.RuntimeType.NamespaceWithoutGlobal); ClassBuilder classBuilder = ClassBuilder .New() .AddImplements(TypeNames.IOperationResultDataInfo) .SetName(fileName); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(complexTypeDescriptor.RuntimeType.Name); foreach (var prop in complexTypeDescriptor.Properties) { TypeReferenceBuilder propTypeBuilder = prop.Type.ToStateTypeReference(); // Add Property to class classBuilder .AddProperty(prop.Name) .SetComment(prop.Description) .SetType(propTypeBuilder) .SetPublic(); // Add initialization of property to the constructor var paramName = GetParameterName(prop.Name); constructorBuilder.AddParameter(paramName).SetType(propTypeBuilder); constructorBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide(prop.Name) .SetRighthandSide(paramName)); } classBuilder .AddProperty("EntityIds") .SetType(TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId)) .AsLambda(settings.IsStoreEnabled() ? CodeInlineBuilder.From(_entityIds) : MethodCallBuilder.Inline() .SetMethodName(TypeNames.Array, "Empty") .AddGeneric(TypeNames.EntityId)); classBuilder .AddProperty("Version") .SetType(TypeNames.UInt64) .AsLambda(settings.IsStoreEnabled() ? _version : "0"); if (settings.IsStoreEnabled()) { AddConstructorAssignedField( TypeNames.IReadOnlyCollection.WithGeneric(TypeNames.EntityId), _entityIds, entityIds, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeNames.UInt64, _version, version, classBuilder, constructorBuilder, true); } // WithVersion classBuilder .AddMethod("WithVersion") .SetAccessModifier(AccessModifier.Public) .SetReturnType(TypeNames.IOperationResultDataInfo) .AddParameter(version, x => x.SetType(TypeNames.UInt64)) .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(className) .AddArgumentRange( complexTypeDescriptor.Properties.Select(x => x.Name.Value)) .If(settings.IsStoreEnabled(), x => x.AddArgument(_entityIds).AddArgument(version))); classBuilder.Build(writer); }
protected override void Generate( CodeWriter writer, ResultBuilderDescriptor resultBuilderDescriptor, out string fileName, out string?path) { InterfaceTypeDescriptor resultTypeDescriptor = resultBuilderDescriptor.ResultNamedType as InterfaceTypeDescriptor ?? throw new InvalidOperationException( "A result type can only be generated for complex types"); fileName = resultBuilderDescriptor.RuntimeType.Name; path = State; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); classBuilder .AddImplements( TypeNames.IOperationResultBuilder.WithGeneric( TypeNames.JsonDocument, resultTypeDescriptor.RuntimeType.ToString())); AddConstructorAssignedField( TypeNames.IEntityStore, _entityStore, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeNames.IEntityIdSerializer, _idSerializer, classBuilder, constructorBuilder); AddConstructorAssignedField( TypeNames.IOperationResultDataFactory .WithGeneric(resultTypeDescriptor.RuntimeType.ToString()), _resultDataFactory, classBuilder, constructorBuilder); constructorBuilder .AddParameter(_serializerResolver) .SetType(TypeNames.ISerializerResolver); IEnumerable <ValueParserDescriptor> valueParsers = resultBuilderDescriptor .ValueParsers .GroupBy(t => t.Name) .Select(t => t.First()); foreach (ValueParserDescriptor valueParser in valueParsers) { var parserFieldName = $"{GetFieldName(valueParser.Name)}Parser"; classBuilder .AddField(parserFieldName) .SetReadOnly() .SetType( TypeNames.ILeafValueParser .WithGeneric(valueParser.SerializedType, valueParser.RuntimeType)); MethodCallBuilder getLeaveValueParser = MethodCallBuilder .Inline() .SetMethodName(_serializerResolver, "GetLeafValueParser") .AddGeneric(valueParser.SerializedType.ToString()) .AddGeneric(valueParser.RuntimeType.ToString()) .AddArgument(valueParser.Name.AsStringToken()); constructorBuilder.AddCode( AssignmentBuilder .New() .SetAssertNonNull() .SetAssertException( ExceptionBuilder .Inline(TypeNames.ArgumentException) .AddArgument( $"\"No serializer for type `{valueParser.Name}` found.\"")) .SetLefthandSide(parserFieldName) .SetRighthandSide(getLeaveValueParser)); } AddBuildMethod(resultTypeDescriptor, classBuilder); AddBuildDataMethod(resultTypeDescriptor, classBuilder); var processed = new HashSet <string>(); AddRequiredDeserializeMethods(resultTypeDescriptor, classBuilder, processed); CodeFileBuilder .New() .SetNamespace(resultBuilderDescriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
protected override void Generate( CodeWriter writer, DataTypeDescriptor descriptor, out string fileName, out string?path) { fileName = descriptor.RuntimeType.Name; path = State; AbstractTypeBuilder typeBuilder; ConstructorBuilder? constructorBuilder = null; if (descriptor.IsInterface) { typeBuilder = InterfaceBuilder .New() .SetComment(descriptor.Documentation) .SetName(fileName); typeBuilder .AddProperty(WellKnownNames.TypeName) .SetType(TypeNames.String); } else { ClassBuilder classBuilder = ClassBuilder .New() .SetComment(descriptor.Documentation) .SetName(fileName); typeBuilder = classBuilder; classBuilder .AddProperty(WellKnownNames.TypeName) .SetPublic() .SetType(TypeNames.String); constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); constructorBuilder .AddParameter(WellKnownNames.TypeName) .SetType(TypeNames.String) .SetName(WellKnownNames.TypeName); constructorBuilder .AddCode( AssignmentBuilder .New() .SetLefthandSide("this." + WellKnownNames.TypeName) .SetRighthandSide(WellKnownNames.TypeName) .AssertNonNull()); } // Add Properties to class foreach (PropertyDescriptor property in descriptor.Properties) { if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName)) { continue; } TypeReferenceBuilder propertyType = property.Type.ToStateTypeReference(); typeBuilder .AddProperty(property.Name) .SetComment(property.Description) .SetType(propertyType) .SetPublic(); var parameterName = GetParameterName(property.Name); constructorBuilder? .AddParameter(parameterName) .SetType(propertyType) .SetDefault("null"); constructorBuilder? .AddCode(AssignmentBuilder .New() .SetLefthandSide(property.Name) .SetRighthandSide(parameterName)); } // implement interfaces typeBuilder.AddImplementsRange(descriptor.Implements.Select(CreateDataTypeName)); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(typeBuilder) .Build(writer); }