protected override void Generate( CodeWriter writer, EntityTypeDescriptor descriptor, out string fileName, out string?path) { // Setup class fileName = descriptor.RuntimeType.Name; path = State; ClassBuilder classBuilder = ClassBuilder .New() .SetComment(descriptor.Documentation) .SetName(fileName); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetPublic() .SetTypeName(fileName); // Add Properties to class foreach (KeyValuePair <string, PropertyDescriptor> item in descriptor.Properties) { classBuilder .AddProperty(item.Value.Name) .SetComment(item.Value.Description) .SetType(item.Value.Type.ToStateTypeReference()) .SetPublic(); var paramName = item.Value.Name == WellKnownNames.TypeName ? WellKnownNames.TypeName : GetParameterName(item.Value.Name); constructorBuilder .AddParameter( paramName, x => x.SetType(item.Value.Type.ToStateTypeReference())) .AddCode(AssignmentBuilder .New() .SetLefthandSide( (item.Value.Name == WellKnownNames.TypeName ? "this." : string.Empty) + item.Value.Name) .SetRighthandSide(paramName)); } CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
protected override void Generate( CodeWriter writer, ObjectTypeDescriptor descriptor, out string fileName, out string?path) { fileName = descriptor.RuntimeType.Name; path = null; ClassBuilder classBuilder = ClassBuilder .New() .SetComment(descriptor.Description) .SetName(fileName) .AddEquality(fileName, descriptor.Properties); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); foreach (var prop in descriptor.Properties) { TypeReferenceBuilder propTypeBuilder = prop.Type.ToTypeReference(); // Add Property to class classBuilder .AddProperty(prop.Name) .SetComment(prop.Description) .SetName(prop.Name) .SetType(propTypeBuilder) .SetPublic(); // Add initialization of property to the constructor var paramName = GetParameterName(prop.Name); constructorBuilder .AddParameter(paramName, x => x.SetType(propTypeBuilder)) .AddCode(AssignmentBuilder .New() .SetLefthandSide( (prop.Name.Value is WellKnownNames.TypeName ? "this." : string.Empty) + prop.Name) .SetRighthandSide(paramName)); } classBuilder.AddImplementsRange(descriptor.Implements.Select(x => x.Value)); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
protected override void Generate( ClientDescriptor descriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { fileName = descriptor.Name; path = null; ns = descriptor.RuntimeType.NamespaceWithoutGlobal; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .SetComment(descriptor.Documentation) .AddImplements(descriptor.InterfaceType.ToString()); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); classBuilder .AddProperty("ClientName") .SetPublic() .SetStatic() .SetType(TypeNames.String) .AsLambda(descriptor.Name.Value.AsStringToken()); foreach (OperationDescriptor operation in descriptor.Operations) { AddConstructorAssignedField( operation.InterfaceType.ToString(), GetFieldName(operation.Name), GetParameterName(operation.Name), classBuilder, constructorBuilder); classBuilder .AddProperty(GetPropertyName(operation.Name)) .SetPublic() .SetType(operation.InterfaceType.ToString()) .AsLambda(GetFieldName(operation.Name)); } classBuilder.Build(writer); }
public override void Build(RuntimeState state, ClassBuilder builder) { List <string> parameters = new List <string>(); foreach (Name parameter in this.parameters) { parameters.Add(parameter.name); } Method method = new Method( builder.TypeBuilder.Name + ".constructor", "constructor for " + builder.TypeBuilder.Name, true, parameters); method.SetCodeTree(body.BuildCodeTree(state)); builder.AddConstructor(method); }
protected override void Generate( CodeWriter writer, StoreAccessorDescriptor descriptor, out string fileName, out string?path) { fileName = descriptor.Name; path = State; ClassBuilder factory = ClassBuilder .New(fileName) .SetAccessModifier(AccessModifier.Public) .AddImplements(TypeNames.StoreAccessor); factory .AddConstructor() .SetTypeName(fileName) .SetPublic() .AddParameter(_operationStore, x => x.SetType(TypeNames.IOperationStore)) .AddParameter(_entityStore, x => x.SetType(TypeNames.IEntityStore)) .AddParameter(_entityIdSerializer, x => x.SetType(TypeNames.IEntityIdSerializer)) .AddParameter( _requestFactories, x => x.SetType( TypeNames.IEnumerable.WithGeneric(TypeNames.IOperationRequestFactory))) .AddParameter( _resultDataFactories, x => x.SetType( TypeNames.IEnumerable.WithGeneric(TypeNames.IOperationResultDataFactory))) .AddBase(_operationStore) .AddBase(_entityStore) .AddBase(_entityIdSerializer) .AddBase(_requestFactories) .AddBase(_resultDataFactories); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(factory) .Build(writer); }
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(ITypeDescriptor typeDescriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { ComplexTypeDescriptor descriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result data factory can only be generated for complex types"); fileName = CreateResultFactoryName(descriptor.RuntimeType.Name); path = State; ns = CreateStateNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal); ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .AddImplements( TypeNames.IOperationResultDataFactory.WithGeneric(descriptor.RuntimeType)); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(descriptor.Name); if (settings.IsStoreEnabled()) { AddConstructorAssignedField( TypeNames.IEntityStore, _entityStore, entityStore, classBuilder, constructorBuilder); } MethodCallBuilder returnStatement = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(descriptor.RuntimeType.Name); foreach (PropertyDescriptor property in descriptor.Properties) { returnStatement .AddArgument(BuildMapMethodCall(settings, _info, property)); } IfBuilder ifHasCorrectType = IfBuilder .New() .SetCondition( $"{_dataInfo} is {CreateResultInfoName(descriptor.RuntimeType.Name)} {_info}") .AddCode(returnStatement); MethodBuilder createMethod = classBuilder .AddMethod("Create") .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.RuntimeType.Name) .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo)) .AddParameter( _snapshot, b => b.SetDefault("null") .SetType(TypeNames.IEntityStoreSnapshot.MakeNullable())); if (settings.IsStoreEnabled()) { createMethod .AddCode( IfBuilder.New() .SetCondition($"{_snapshot} is null") .AddCode( AssignmentBuilder .New() .SetLefthandSide(_snapshot) .SetRighthandSide($"{_entityStore}.CurrentSnapshot"))) .AddEmptyLine(); } createMethod.AddCode(ifHasCorrectType) .AddEmptyLine() .AddCode( ExceptionBuilder .New(TypeNames.ArgumentException) .AddArgument( $"\"{CreateResultInfoName(descriptor.RuntimeType.Name)} expected.\"")); var processed = new HashSet <string>(); AddRequiredMapMethods( settings, _info, descriptor, classBuilder, constructorBuilder, processed, true); classBuilder .AddProperty("ResultType") .SetType(TypeNames.Type) .AsLambda($"typeof({descriptor.RuntimeType.Namespace}.{descriptor.Implements[0]})") .SetInterface(TypeNames.IOperationResultDataFactory); classBuilder .AddMethod("Create") .SetInterface(TypeNames.IOperationResultDataFactory) .SetReturnType(TypeNames.Object) .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo)) .AddParameter( _snapshot, b => b.SetType(TypeNames.IEntityStoreSnapshot.MakeNullable())) .AddCode( MethodCallBuilder .New() .SetReturn() .SetMethodName("Create") .AddArgument(_dataInfo) .AddArgument(_snapshot)); 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(ITypeDescriptor typeDescriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { // Setup class ComplexTypeDescriptor descriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result entity mapper can only be generated for complex types"); fileName = descriptor.ExtractMapperName(); path = State; ns = CreateStateNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal); ClassBuilder classBuilder = ClassBuilder .New() .AddImplements( TypeNames.IEntityMapper .WithGeneric( descriptor.ExtractType().ToString(), descriptor.RuntimeType.Name)) .SetName(fileName); ConstructorBuilder constructorBuilder = ConstructorBuilder .New() .SetTypeName(descriptor.Name); AddConstructorAssignedField( TypeNames.IEntityStore, _entityStore, entityStore, classBuilder, constructorBuilder); // Define map method MethodBuilder mapMethod = MethodBuilder .New() .SetName(_map) .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.RuntimeType.Name) .AddParameter( ParameterBuilder .New() .SetType( descriptor.Kind == TypeKind.Entity ? CreateEntityType( descriptor.Name, descriptor.RuntimeType.NamespaceWithoutGlobal) .ToString() : descriptor.Name) .SetName(_entity)) .AddParameter( _snapshot, b => b.SetDefault("null") .SetType(TypeNames.IEntityStoreSnapshot.MakeNullable())); mapMethod .AddCode(IfBuilder .New() .SetCondition($"{_snapshot} is null") .AddCode(AssignmentBuilder .New() .SetLefthandSide(_snapshot) .SetRighthandSide($"{_entityStore}.CurrentSnapshot"))) .AddEmptyLine(); MethodCallBuilder constructorCall = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(descriptor.RuntimeType.Name); if (typeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { foreach (PropertyDescriptor property in complexTypeDescriptor.Properties) { constructorCall.AddArgument(BuildMapMethodCall(settings, _entity, property)); } } mapMethod.AddCode(constructorCall); if (constructorBuilder.HasParameters()) { classBuilder.AddConstructor(constructorBuilder); } classBuilder.AddMethod(mapMethod); AddRequiredMapMethods( settings, _entity, descriptor, classBuilder, constructorBuilder, new HashSet <string>()); classBuilder.Build(writer); }
protected override void Generate(OperationDescriptor descriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { var documentName = CreateDocumentTypeName(descriptor.RuntimeType.Name); fileName = documentName; path = null; ns = descriptor.RuntimeType.NamespaceWithoutGlobal; string operationKind = descriptor switch { MutationOperationDescriptor => "Mutation", QueryOperationDescriptor => "Query", SubscriptionOperationDescriptor => "Subscription", _ => throw new ArgumentOutOfRangeException(nameof(descriptor)) }; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .AddImplements(TypeNames.IDocument) .SetComment( XmlCommentBuilder .New() .SetSummary( string.Format( CodeGenerationResources.OperationServiceDescriptor_Description, descriptor.Name)) .AddCode(descriptor.BodyString)); classBuilder .AddConstructor() .SetPrivate(); classBuilder .AddProperty("Instance") .SetStatic() .SetType(documentName) .SetValue($"new {documentName}()"); classBuilder .AddProperty("Kind") .SetType(TypeNames.OperationKind) .AsLambda($"{TypeNames.OperationKind}.{operationKind}"); if (descriptor.Strategy == RequestStrategy.PersistedQuery) { classBuilder .AddProperty("Body") .SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte)) .AsLambda($"new {TypeNames.Byte}[0]"); } else { classBuilder .AddProperty("Body") .SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte)) .AsLambda(GetByteArray(descriptor.Body)); } classBuilder .AddProperty("Hash") .SetType(TypeNames.DocumentHash) .SetValue( $@"new {TypeNames.DocumentHash}(" + $@"""{descriptor.HashAlgorithm}"", " + $@"""{descriptor.HashValue}"")"); classBuilder .AddMethod("ToString") .SetPublic() .SetOverride() .SetReturnType(TypeNames.String) .AddCode("#if NETSTANDARD2_0") .AddCode(MethodCallBuilder .New() .SetReturn() .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString)) .AddArgument("Body.ToArray()")) .AddCode("#else") .AddCode(MethodCallBuilder .New() .SetReturn() .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString)) .AddArgument("Body")) .AddCode("#endif"); 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); }
protected override void Generate( CodeWriter writer, OperationDescriptor descriptor, out string fileName, out string?path) { fileName = descriptor.RuntimeType.Name; path = null; ClassBuilder classBuilder = ClassBuilder .New() .SetComment( XmlCommentBuilder .New() .SetSummary( string.Format( CodeGenerationResources.OperationServiceDescriptor_Description, descriptor.Name)) .AddCode(descriptor.BodyString)) .AddImplements(descriptor.InterfaceType.ToString()) .SetName(fileName); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); var runtimeTypeName = descriptor.ResultTypeReference.GetRuntimeType().Name; AddConstructorAssignedField( TypeNames.IOperationExecutor.WithGeneric(runtimeTypeName), _operationExecutor, classBuilder, constructorBuilder); AddInjectedSerializers(descriptor, constructorBuilder, classBuilder); if (descriptor is not SubscriptionOperationDescriptor) { classBuilder.AddMethod(CreateExecuteMethod(descriptor, runtimeTypeName)); } classBuilder.AddMethod(CreateWatchMethod(descriptor, runtimeTypeName)); classBuilder.AddMethod(CreateRequestMethod(descriptor)); classBuilder.AddMethod(CreateRequestVariablesMethod(descriptor)); AddFormatMethods(descriptor, classBuilder); classBuilder .AddProperty("ResultType") .SetType(TypeNames.Type) .AsLambda($"typeof({runtimeTypeName})") .SetInterface(TypeNames.IOperationRequestFactory); MethodCallBuilder createRequestCall = MethodCallBuilder .New() .SetReturn() .SetMethodName(_createRequest); if (descriptor.Arguments.Count > 0) { createRequestCall.AddArgument($"{_variables}!"); } classBuilder .AddMethod("Create") .SetReturnType(TypeNames.OperationRequest) .SetInterface(TypeNames.IOperationRequestFactory) .AddParameter( _variables, x => x.SetType( TypeNames.IReadOnlyDictionary .WithGeneric(TypeNames.String, TypeNames.Object.MakeNullable()) .MakeNullable())) .AddCode(createRequestCall); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }