private static AssignmentBuilder CreateDataError( string exception = "ex") { string dict = TypeNames.Dictionary.WithGeneric( TypeNames.String, TypeNames.Object.MakeNullable()); string body = "response.Body?.RootElement.ToString()"; MethodCallBuilder createClientError = MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ClientError) .AddArgument($"{exception}.Message") .AddArgument($"exception: {exception}") .AddArgument($"extensions: new {dict} {{ {{ \"body\", {body} }} }}"); return(AssignmentBuilder.New() .SetLefthandSide("errors") .SetRighthandSide( ArrayBuilder.New() .SetDetermineStatement(false) .SetType(TypeNames.IClientError) .AddAssignment(createClientError))); }
private static ICode RegisterHttpConnection(string clientName) => MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddArgument(_services) .AddGeneric(TypeNames.IHttpConnection) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetBlock(true) .SetCode(CodeBlockBuilder .New() .AddCode(AssignmentBuilder .New() .SetLefthandSide($"var {_clientFactory}") .SetRighthandSide(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(TypeNames.IHttpClientFactory) .AddArgument(_parentServices))) .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(TypeNames.HttpConnection) .AddArgument(LambdaBuilder .New() .SetCode(MethodCallBuilder .Inline() .SetMethodName( _clientFactory, nameof(IHttpClientFactory.CreateClient)) .AddArgument(clientName.AsStringToken()))))));
private static ICode RegisterWebSocketConnection(string clientName) => MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetBlock(true) .SetCode(CodeBlockBuilder .New() .AddCode(AssignmentBuilder .New() .SetLefthandSide($"var {_sessionPool}") .SetRighthandSide(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(TypeNames.ISessionPool) .AddArgument(_parentServices))) .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(TypeNames.WebSocketConnection) .AddArgument(LambdaBuilder .New() .SetCode(MethodCallBuilder .Inline() .SetMethodName( _sessionPool, nameof(ISessionPool.CreateAsync)) .AddArgument(clientName.AsStringToken()) .AddArgument("default"))))));
protected void AddConstructorAssignedField( TypeReferenceBuilder type, string fieldName, ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, bool skipNullCheck = false) { var paramName = fieldName.TrimStart('_'); classBuilder.AddField( FieldBuilder .New() .SetReadOnly() .SetName(fieldName) .SetType(type)); var assignment = AssignmentBuilder .New() .SetLefthandSide(fieldName) .SetRighthandSide(paramName); if (!skipNullCheck) { assignment.AssertNonNull(); } constructorBuilder .AddCode(assignment) .AddParameter(paramName, b => b.SetType(type)); }
private void AddInterfaceDataTypeDeserializerToMethod( MethodBuilder methodBuilder, InterfaceTypeDescriptor interfaceTypeDescriptor) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_typename}") .SetRighthandSide(MethodCallBuilder .Inline() .SetMethodName( _obj, "Value", nameof(JsonElement.GetProperty)) .AddArgument(WellKnownNames.TypeName.AsStringToken()) .Chain(x => x.SetMethodName(nameof(JsonElement.GetString))))); // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { MethodCallBuilder returnStatement = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName( $"{concreteType.RuntimeType.Namespace}.State." + CreateDataTypeName(concreteType.Name)) .AddArgument("typename"); foreach (PropertyDescriptor property in concreteType.Properties) { if (property.Name.Value.EqualsOrdinal(WellKnownNames.TypeName)) { continue; } returnStatement.AddArgument( CodeBlockBuilder .New() .AddCode($"{GetParameterName(property.Name)}: ") .AddCode(BuildUpdateMethodCall(property))); } IfBuilder ifStatement = IfBuilder .New() .SetCondition( $"typename?.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison}) ?? false") .AddCode(returnStatement); methodBuilder .AddEmptyLine() .AddCode(ifStatement); } methodBuilder .AddEmptyLine() .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); }
private void AddArrayHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder.AddParameter( ParameterBuilder.New() .SetType(listTypeDescriptor.ToEntityIdBuilder()) .SetName(ListParamName)); var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s"; if (!isNonNullable) { methodBuilder.AddCode(EnsureProperNullability(ListParamName, isNonNullable)); } methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder.New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode( listTypeDescriptor.InnerType.ToBuilder() .SkipTrailingSpace()) .AddCode(">") .AddCode("()"))); methodBuilder.AddEmptyLine(); var loopbuilder = ForEachBuilder.New() .SetLoopHeader( CodeBlockBuilder.New() .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder()) .AddCode($"child in {ListParamName}")) .AddCode( MethodCallBuilder.New() .SetPrefix($"{listVarName}.") .SetMethodName("Add") .AddArgument( BuildMapMethodCall( listTypeDescriptor.InnerType, "child"))); methodBuilder.AddCode(loopbuilder); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {listVarName};"); AddMapMethod( listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
private IfBuilder GenerateDataInterfaceIfClause( ObjectTypeDescriptor objectTypeDescriptor, bool isNonNullable, string variableName) { ICode ifCondition = MethodCallBuilder .Inline() .SetMethodName( _dataParameterName.MakeNullable(!isNonNullable), WellKnownNames.TypeName, nameof(string.Equals)) .AddArgument(objectTypeDescriptor.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison); if (!isNonNullable) { ifCondition = NullCheckBuilder .New() .SetCondition(ifCondition) .SetSingleLine() .SetDetermineStatement(false) .SetCode("false"); } MethodCallBuilder constructorCall = MethodCallBuilder .Inline() .SetNew() .SetMethodName(objectTypeDescriptor.RuntimeType.Name); foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties) { var propAccess = $"{_dataParameterName}.{prop.Name}"; if (prop.Type.IsEntityType() || prop.Type.IsDataType()) { constructorCall.AddArgument(BuildMapMethodCall(_dataParameterName, prop, true)); } else if (prop.Type.IsNullableType()) { constructorCall.AddArgument(propAccess); } else { constructorCall .AddArgument( NullCheckBuilder .Inline() .SetCondition(propAccess) .SetCode(ExceptionBuilder.Inline(TypeNames.ArgumentNullException))); } } return(IfBuilder .New() .SetCondition(ifCondition) .AddCode(AssignmentBuilder .New() .SetLefthandSide(variableName) .SetRighthandSide(constructorCall))); }
private void AddBuildMethod( InterfaceTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var responseParameterName = "response"; var buildMethod = MethodBuilder .New() .SetAccessModifier(AccessModifier.Public) .SetName("Build") .SetReturnType( TypeReferenceBuilder.New() .SetName(TypeNames.IOperationResult) .AddGeneric(resultNamedType.RuntimeType.Name)) .AddParameter( ParameterBuilder.New() .SetType( TypeReferenceBuilder.New() .SetName(TypeNames.Response) .AddGeneric(TypeNames.JsonDocument) .SetName(TypeNames.Response)) .SetName(responseParameterName)); var concreteResultType = CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name); buildMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide( $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " + "Info)? data") .SetRighthandSide("null")); buildMethod.AddEmptyLine(); buildMethod.AddCode( IfBuilder.New() .SetCondition( ConditionBuilder.New() .Set("response.Body is not null") .And("response.Body.RootElement.TryGetProperty(\"data\"," + $" out {TypeNames.JsonElement} obj)")) .AddCode("data = BuildData(obj);")); buildMethod.AddEmptyLine(); buildMethod.AddCode( MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName( TypeNames.OperationResult.WithGeneric(resultNamedType.RuntimeType.Name)) .AddArgument("data?.Result") .AddArgument("data?.Info") .AddArgument(_resultDataFactoryFieldName) .AddArgument("null")); classBuilder.AddMethod(buildMethod); }
private void WritePropertyAssignments <T>(ICodeContainer <T> codeContainer, IReadOnlyList <PropertyDescriptor> properties, string entityVarName) { foreach (PropertyDescriptor property in properties) { codeContainer.AddCode( AssignmentBuilder.New() .SetLefthandSide($"{entityVarName}.{property.Name}") .SetRighthandSide(BuildUpdateMethodCall(property))); } }
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); }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.EntityId} {_entityId}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_idSerializer, "Parse") .AddArgument($"{_obj}.Value"))); methodBuilder.AddCode( MethodCallBuilder .New() .SetMethodName(_entityIds, nameof(List <object> .Add)) .AddArgument(_entityId)); methodBuilder.AddEmptyLine(); if (namedTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { methodBuilder .AddEmptyLine() .AddCode(CreateUpdateEntityStatement(concreteType) .AddCode($"return {_entityId};")); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); } else if (namedTypeDescriptor is ObjectTypeDescriptor objectTypeDescriptor) { BuildTryGetEntityIf( CreateEntityType( objectTypeDescriptor.Name, objectTypeDescriptor.RuntimeType.NamespaceWithoutGlobal)) .AddCode(CreateEntityConstructorCall(objectTypeDescriptor, false)) .AddElse(CreateEntityConstructorCall(objectTypeDescriptor, true)); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {_entityId};"); } AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed); }
public static AssignmentBuilder AddAssigment( this CodeBlockBuilder builder, string assignedTo) { AssignmentBuilder assignmentBuilder = AssignmentBuilder .New() .SetLefthandSide(assignedTo); builder.AddCode(assignmentBuilder); return(assignmentBuilder); }
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); }
private void WriteEntityLoader <T>( ICodeContainer <T> codeContainer, string entityTypeName) { codeContainer.AddCode( AssignmentBuilder .New() .SetLefthandSide($"{entityTypeName} {_entity}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_entityStore, nameof(IEntityStore.GetOrCreate)) .AddGeneric(entityTypeName) .AddArgument(_entityId))); }
public static AssignmentBuilder AddAssigment( this CodeBlockBuilder builder, string?assignedTo = null) { AssignmentBuilder assignmentBuilder = AssignmentBuilder .New(); if (assignedTo is not null) { assignmentBuilder.SetLefthandSide(assignedTo); } builder.AddCode(assignmentBuilder); return(assignmentBuilder); }
private static ICode GenerateMethodBody(DependencyInjectionDescriptor descriptor) => CodeBlockBuilder .New() .AddMethodCall(x => x.SetMethodName(TypeNames.AddSingleton) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .SetBlock(true) .AddArgument(_sp) .SetCode( CodeBlockBuilder .New() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_serviceCollection}") .SetRighthandSide( MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ServiceCollection))) .AddEmptyLine() .AddMethodCall(x => x.SetMethodName("ConfigureClient") .AddArgument(_serviceCollection) .AddArgument(_sp) .AddArgument(_strategy)) .AddEmptyLine() .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName("ClientServiceProvider") .SetWrapArguments() .AddArgument(MethodCallBuilder .Inline() .SetMethodName(TypeNames.BuildServiceProvider) .AddArgument(_serviceCollection)))))) .AddEmptyLine() .ForEach( descriptor.Operations, (builder, operation) => builder.AddCode(ForwardSingletonToClientServiceProvider(operation.Name))) .AddEmptyLine() .AddCode(ForwardSingletonToClientServiceProvider(descriptor.Name)) .AddEmptyLine() .AddLine($"return {_services};");
private void AddArrayHandler( ClassBuilder classBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed) { var listVarName = GetParameterName(listTypeDescriptor.Name) + "s"; methodBuilder .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder .New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode( listTypeDescriptor.InnerType .ToStateTypeReference() .SkipTrailingSpace()) .AddCode(">") .AddCode("()"))) .AddEmptyLine() .AddCode( ForEachBuilder .New() .SetLoopHeader( $"{TypeNames.JsonElement} {_child} in {_obj}.Value.EnumerateArray()") .AddCode( MethodCallBuilder .New() .SetMethodName(listVarName, nameof(List <object> .Add)) .AddArgument( BuildUpdateMethodCall( listTypeDescriptor.InnerType, CodeInlineBuilder.From(_child))))) .AddEmptyLine() .AddCode($"return {listVarName};"); AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed); }
protected override void Generate( CodeWriter writer, ObjectTypeDescriptor descriptor, out string fileName) { fileName = descriptor.RuntimeType.Name; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); foreach (var prop in descriptor.Properties) { TypeReferenceBuilder propTypeBuilder = prop.Type.ToBuilder(); // Add Property to class classBuilder .AddProperty(prop.Name) .SetName(prop.Name) .SetType(propTypeBuilder) .SetPublic() .SetValue(prop.Type.IsNullableType() ? "default!" : null); // 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) .SetRighthandSide(paramName)); } classBuilder.AddImplementsRange(descriptor.Implements.Select(x => x.Value)); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }
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(); }
private static ICode GenerateMethodBody( CSharpSyntaxGeneratorSettings settings, DependencyInjectionDescriptor descriptor) => CodeBlockBuilder .New() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_serviceCollection}") .SetRighthandSide(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ServiceCollection))) .AddMethodCall(x => x .SetMethodName(TypeNames.AddSingleton) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .SetBlock(true) .AddArgument(_sp) .SetCode(GenerateClientServiceProviderFactory(descriptor)))) .AddEmptyLine() .AddCode(RegisterStoreAccessor(settings, descriptor.StoreAccessor)) .AddEmptyLine() .ForEach( descriptor.Operations, (builder, operation) => builder.AddCode(ForwardSingletonToClientServiceProvider( operation.RuntimeType.ToString()))) .AddEmptyLine() .AddCode(ForwardSingletonToClientServiceProvider( descriptor.ClientDescriptor.RuntimeType.ToString())) .AddCode(ForwardSingletonToClientServiceProvider( descriptor.ClientDescriptor.InterfaceType.ToString())) .AddEmptyLine() .AddMethodCall(x => x .SetReturn() .SetNew() .SetMethodName( TypeNames.ClientBuilder.WithGeneric(descriptor.StoreAccessor.RuntimeType)) .AddArgument(descriptor.Name.AsStringToken()) .AddArgument(_services) .AddArgument(_serviceCollection));
private static ICode BuildProperty( ITypeDescriptor type, string propertyName) { return(BuildPropertyInternal(type, propertyName, true)); ICode BuildPropertyInternal( ITypeDescriptor currentType, string variableName, bool isNullable) { ICode check = currentType switch { NonNullTypeDescriptor d => BuildPropertyInternal(d.InnerType, variableName, false), INamedTypeDescriptor => AssignmentBuilder .New() .SetLefthandSide(HashCodeBuilder.VariableName) .SetOperator("^=") .SetRighthandSide(MethodCallBuilder .Inline() .SetPrefix($"{HashCodeBuilder.Prime} * ") .SetMethodName(variableName, nameof(GetHashCode))), ListTypeDescriptor d => ForEachBuilder .New() .SetLoopHeader($"var {variableName}_elm in {variableName}") .AddCode(BuildPropertyInternal(d.InnerType, variableName + "_elm", true)), _ => throw new ArgumentOutOfRangeException() }; if (isNullable && currentType is not NonNullTypeDescriptor) { return(IfBuilder .New() .SetCondition($"!({variableName} is null)") .AddCode(check)); } return(check); } } }
private ICode ParseEntityIdBody(EntityIdFactoryDescriptor descriptor) { AssignmentBuilder typeNameAssignment = AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.String} {WellKnownNames.TypeName}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_obj, nameof(JsonElement.GetProperty)) .AddArgument(WellKnownNames.TypeName.AsStringToken()) .Chain(x => x .SetMethodName(nameof(JsonElement.GetString)) .SetNullForgiving())); SwitchExpressionBuilder typeNameSwitch = SwitchExpressionBuilder .New() .SetReturn() .SetExpression(WellKnownNames.TypeName) .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.NotSupportedException)); foreach (var entity in descriptor.Entities) { typeNameSwitch.AddCase( entity.Name.AsStringToken(), MethodCallBuilder .Inline() .SetMethodName($"Parse{entity.Name}EntityId") .AddArgument(_obj) .AddArgument(WellKnownNames.TypeName)); } return(CodeBlockBuilder .New() .AddCode(typeNameAssignment) .AddEmptyLine() .AddCode(typeNameSwitch)); }
private void AddArrayHandler( ClassBuilder classBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed) { var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s"; methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder.New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder() .SkipTrailingSpace()) .AddCode(">") .AddCode("()") )); methodBuilder.AddEmptyLine(); methodBuilder.AddCode( ForEachBuilder.New() .SetLoopHeader( $"{TypeNames.JsonElement} child in {_objParamName}.Value.EnumerateArray()") .AddCode( MethodCallBuilder.New() .SetPrefix($"{listVarName}.") .SetMethodName("Add") .AddArgument( BuildUpdateMethodCall(listTypeDescriptor.InnerType, "child")))); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {listVarName};"); AddDeserializeMethod(listTypeDescriptor.InnerType, classBuilder, processed); }
private void AddInterfaceDataTypeDeserializerToMethod( MethodBuilder methodBuilder, InterfaceTypeDescriptor interfaceTypeDescriptor) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_typename}") .SetRighthandSide(MethodCallBuilder .Inline() .SetMethodName( _obj, "Value", nameof(JsonElement.GetProperty)) .AddArgument(WellKnownNames.TypeName.AsStringToken()) .Chain(x => x.SetMethodName(nameof(JsonElement.GetString))))); // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { MethodCallBuilder returnStatement = CreateBuildDataStatement(concreteType) .SetReturn(); IfBuilder ifStatement = IfBuilder .New() .SetCondition( $"typename?.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison}) ?? false") .AddCode(returnStatement); methodBuilder .AddEmptyLine() .AddCode(ifStatement); } methodBuilder .AddEmptyLine() .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); }
private IfBuilder GenerateComplexDataInterfaceIfClause( ObjectTypeDescriptor objectTypeDescriptor, string variableName) { var matchedTypeName = GetParameterName(objectTypeDescriptor.Name); // since we want to create the data name we will need to craft the type name // by hand by using the GraphQL type name and the state namespace. var dataTypeName = new RuntimeTypeInfo( CreateDataTypeName(objectTypeDescriptor.Name), $"{objectTypeDescriptor.RuntimeType.Namespace}.State"); MethodCallBuilder constructorCall = MethodCallBuilder .Inline() .SetNew() .SetMethodName(objectTypeDescriptor.RuntimeType.ToString()); foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties) { if (prop.Type.IsEntityType()) { constructorCall.AddArgument(BuildMapMethodCall(matchedTypeName, prop)); } else { constructorCall.AddArgument($"{matchedTypeName}.{prop.Name}"); } } return(IfBuilder .New() .SetCondition($"{_dataParameterName} is {dataTypeName} {matchedTypeName}") .AddCode( AssignmentBuilder .New() .SetLefthandSide(variableName) .SetRighthandSide(constructorCall))); }
private static ICode GenerateMethodBody(DependencyInjectionDescriptor descriptor) => CodeBlockBuilder.New() .AddMethodCall(x => x.SetMethodName(TypeNames.AddSingleton) .AddArgument("services") .AddArgument(LambdaBuilder.New() .SetBlock(true) .AddArgument("sp") .SetCode( CodeBlockBuilder.New() .AddCode( AssignmentBuilder.New() .SetLefthandSide("var serviceCollection") .SetRighthandSide( $"new {TypeNames.ServiceCollection}()")) .AddEmptyLine() .AddMethodCall(x => x.SetMethodName("ConfigureClient") .AddArgument("serviceCollection") .AddArgument("sp") .AddArgument("strategy")) .AddEmptyLine() .AddCode(MethodCallBuilder.New() .SetPrefix("return new ") .SetWrapArguments() .SetMethodName("ClientServiceProvider") .AddArgument(MethodCallBuilder.New() .SetMethodName(TypeNames.BuildServiceProvider) .SetDetermineStatement(false) .AddArgument("serviceCollection")))))) .AddEmptyLine() .ForEach( descriptor.Operations, (builder, operation) => builder.AddCode(ForwardSingletonToClientServiceProvider(operation.Name))) .AddEmptyLine() .AddCode(ForwardSingletonToClientServiceProvider(descriptor.Name)) .AddEmptyLine() .AddLine("return services;");
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, DataTypeDescriptor descriptor, out string fileName) { fileName = descriptor.RuntimeType.Name; AbstractTypeBuilder typeBuilder; ConstructorBuilder? constructorBuilder = null; if (descriptor.IsInterface) { typeBuilder = InterfaceBuilder .New() .SetName(fileName); typeBuilder .AddProperty(__typename) .SetType(TypeNames.String); } else { ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName); typeBuilder = classBuilder; classBuilder .AddProperty(__typename) .SetPublic() .SetType(TypeNames.String); constructorBuilder = classBuilder .AddConstructor() .SetTypeName(fileName); constructorBuilder .AddParameter(_typename) .SetType(TypeNames.String) .SetName(_typename); constructorBuilder .AddCode( AssignmentBuilder .New() .SetLefthandSide(__typename) .SetRighthandSide(_typename) .AssertNonNull()); } // Add Properties to class foreach (PropertyDescriptor property in descriptor.Properties) { TypeReferenceBuilder propertyType = property.Type.Kind switch { TypeKind.LeafType => property.Type.ToBuilder(), TypeKind.DataType => property.Type.ToBuilder(property.Type.Name), TypeKind.EntityType => property.Type.ToEntityIdBuilder(), _ => throw new ArgumentOutOfRangeException() }; typeBuilder .AddProperty(property.Name) .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(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); }
private void AddBuildDataMethod( CSharpSyntaxGeneratorSettings settings, InterfaceTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var concreteType = CreateResultInfoName( resultNamedType.ImplementedBy.First().RuntimeType.Name); MethodBuilder buildDataMethod = classBuilder .AddMethod() .SetPrivate() .SetName("BuildData") .SetReturnType($"({resultNamedType.RuntimeType.Name}, {concreteType})") .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement)); if (settings.IsStoreEnabled()) { buildDataMethod.AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_entityIds}") .SetRighthandSide(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.HashSet) .AddGeneric(TypeNames.EntityId))) .AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.IEntityStoreSnapshot} {_snapshot}") .SetRighthandSide("default!")); } buildDataMethod.AddEmptyLine(); CodeBlockBuilder storeUpdateBody = CodeBlockBuilder.New(); if (settings.IsStoreEnabled()) { foreach (PropertyDescriptor property in resultNamedType.Properties.Where(prop => prop.Type.IsOrContainsEntity())) { var variableName = $"{GetParameterName(property.Name)}Id"; buildDataMethod .AddCode(AssignmentBuilder .New() .SetLefthandSide(CodeBlockBuilder .New() .AddCode(property.Type.ToStateTypeReference()) .AddCode(variableName)) .SetRighthandSide("default!")); storeUpdateBody .AddCode(AssignmentBuilder .New() .SetLefthandSide(variableName) .SetRighthandSide(BuildUpdateMethodCall(property))); } storeUpdateBody .AddEmptyLine() .AddCode(AssignmentBuilder .New() .SetLefthandSide(_snapshot) .SetRighthandSide($"{_session}.CurrentSnapshot")); buildDataMethod .AddCode(MethodCallBuilder .New() .SetMethodName(_entityStore, "Update") .AddArgument(LambdaBuilder .New() .AddArgument(_session) .SetBlock(true) .SetCode(storeUpdateBody))); } buildDataMethod .AddEmptyLine() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_resultInfo}") .SetRighthandSide( CreateResultInfoMethodCall(settings, resultNamedType, concreteType))) .AddEmptyLine() .AddCode( TupleBuilder .Inline() .SetDetermineStatement(true) .SetReturn() .AddMember(MethodCallBuilder .Inline() .SetMethodName(_resultDataFactory, "Create") .AddArgument(_resultInfo)) .AddMember(_resultInfo)); }