public TypeDescriptorModel( OutputTypeModel typeModel, NamedTypeDescriptor namedTypeDescriptor) { TypeModel = typeModel; NamedTypeDescriptor = namedTypeDescriptor; }
private void AddScalarTypeDeserializerMethod( MethodBuilder methodBuilder, NamedTypeDescriptor namedType) { string deserializeMethod = namedType.GraphQLTypeName?.Value switch { String => nameof(JsonElement.GetString), ID => nameof(JsonElement.GetString), Url => nameof(JsonElement.GetString), Uuid => nameof(JsonElement.GetString), DateTime => nameof(JsonElement.GetString), Date => nameof(JsonElement.GetString), TimeSpan => nameof(JsonElement.GetString), Boolean => nameof(JsonElement.GetBoolean), Byte => nameof(JsonElement.GetByte), Short => nameof(JsonElement.GetInt16), Int => nameof(JsonElement.GetInt32), Long => nameof(JsonElement.GetInt64), Float => nameof(JsonElement.GetDouble), Decimal => nameof(JsonElement.GetDecimal), ByteArray => nameof(JsonElement.GetBytesFromBase64), _ => "Get" + (namedType.SerializationType?.Split('.').Last() ?? namedType.Name.WithCapitalFirstChar()) }; methodBuilder.AddCode( $"return {namedType.Name.ToFieldName()}Parser.Parse({_objParamName}.Value" + $".{deserializeMethod}()!);"); } }
public InputTypeDescriptorModel( InputObjectTypeModel typeModel, NamedTypeDescriptor namedTypeDescriptor) { TypeModel = typeModel; NamedTypeDescriptor = namedTypeDescriptor; }
private static ITypeDescriptor BuildFieldType( this IType original, NamedTypeDescriptor namedTypeDescriptor) { if (original is NonNullType nnt) { return(new NonNullTypeDescriptor( BuildFieldType( nnt.Type, namedTypeDescriptor))); } if (original is ListType lt) { return(new ListTypeDescriptor( BuildFieldType( lt.ElementType, namedTypeDescriptor))); } if (original is INamedType) { return(namedTypeDescriptor); } throw new NotSupportedException(); }
/// <summary> /// Adds all required deserializers of the given type descriptors properties /// </summary> private void AddRequiredDeserializeMethods( NamedTypeDescriptor namedTypeDescriptor, ClassBuilder classBuilder, HashSet <string> processed) { if (namedTypeDescriptor.IsInterface) { foreach (var @class in namedTypeDescriptor.ImplementedBy) { AddRequiredDeserializeMethods(@class, classBuilder, processed); } } else { foreach (var property in namedTypeDescriptor.Properties) { AddDeserializeMethod( property.Type, classBuilder, processed); if (property.Type.NamedType() is NamedTypeDescriptor nt && !nt.IsLeafType()) { AddRequiredDeserializeMethods(nt, classBuilder, processed); } } } }
public void IsMatch_Match(string name, string version) { // arrange var descriptor = new NamedTypeDescriptor <IInterfaceType>( typeof(ConcreteType), name, version); // act, assert descriptor.IsMatch(name, version).Should().BeTrue(); }
public void Ctor_TypeSet_DerivedType() { // arrange, act var descriptor = new NamedTypeDescriptor <IInterfaceType>(typeof(ConcreteType)); // assert descriptor.Type.Should().Be(typeof(ConcreteType)); descriptor.Name.Should().Be(NameVersionHelper.GetDefaultName(typeof(ConcreteType))); descriptor.Version.Should().Be(NameVersionHelper.GetDefaultVersion(typeof(ConcreteType))); }
public static NameString ExtractMapperName(this NamedTypeDescriptor descriptor) { return(descriptor.Kind == TypeKind.EntityType ? EntityMapperNameFromGraphQLTypeName( descriptor.Name, descriptor.GraphQLTypeName !) : DataMapperNameFromGraphQLTypeName( descriptor.Name, descriptor.GraphQLTypeName !)); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { NamedTypeDescriptor namedTypeDescriptor = typeDescriptor switch { NamedTypeDescriptor nullableNamedType => nullableNamedType, NonNullTypeDescriptor { InnerType : NamedTypeDescriptor namedType } => namedType,
public void Ctor_NameSet_VersionSet() { // arrange, act var descriptor = new NamedTypeDescriptor <IInterfaceType>( typeof(ConcreteType), Name, Version); // assert descriptor.Type.Should().Be(typeof(ConcreteType)); descriptor.Name.Should().Be(Name); descriptor.Version.Should().Be(Version); }
private void AddBuildMethod( NamedTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var responseParameterName = "response"; var buildMethod = MethodBuilder .New() .SetAccessModifier(AccessModifier.Public) .SetName("Build") .SetReturnType( TypeReferenceBuilder.New() .SetName(TypeNames.IOperationResult) .AddGeneric(resultNamedType.Name)) .AddParameter( ParameterBuilder.New() .SetType( TypeReferenceBuilder.New() .SetName(TypeNames.Response) .AddGeneric(TypeNames.JsonDocument) .SetName(TypeNames.Response)) .SetName(responseParameterName)); buildMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide( $"({resultNamedType.Name} Result, " + $"{ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)} " + "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}<{resultNamedType.Name}>") .AddArgument("data?.Result") .AddArgument("data?.Info") .AddArgument(_resultDataFactoryFieldName) .AddArgument("null")); classBuilder.AddMethod(buildMethod); }
public static bool ContainsEntity(this ITypeDescriptor typeDescriptor) { return(typeDescriptor switch { ListTypeDescriptor listTypeDescriptor => listTypeDescriptor.InnerType.ContainsEntity(), NamedTypeDescriptor namedTypeDescriptor => namedTypeDescriptor.Properties.Any(prop => prop.Type.IsEntityType() || prop.Type.ContainsEntity()), NonNullTypeDescriptor nonNullTypeDescriptor => nonNullTypeDescriptor.InnerType.ContainsEntity(), _ => throw new ArgumentOutOfRangeException(nameof(typeDescriptor)) });
public void IsMatch_NoMatch(string name, string version) { // arrange var descriptor = new NamedTypeDescriptor <IInterfaceType>( typeof(ConcreteType), name, version); // act, assert descriptor.IsMatch(name + "1", null).Should().BeFalse(); descriptor.IsMatch(name.ToLower(), null).Should().BeFalse(); descriptor.IsMatch(name.ToUpper(), null).Should().BeFalse(); descriptor.IsMatch(name + "1", version + "1").Should().BeFalse(); descriptor.IsMatch(name.ToLower(), version?.ToLower()).Should().BeFalse(); descriptor.IsMatch(name.ToUpper(), version?.ToUpper()).Should().BeFalse(); }
private MethodCallBuilder GetMappingCall( NamedTypeDescriptor namedTypeDescriptor, string idName) { return(MethodCallBuilder.New() .SetMethodName( EntityMapperNameFromGraphQLTypeName( namedTypeDescriptor.Name, namedTypeDescriptor.GraphQLTypeName ?? throw new ArgumentNullException("GraphQLTypeName")) .ToFieldName() + ".Map") .SetDetermineStatement(false) .AddArgument( $"{StoreParamName}.GetEntity<" + $"{EntityTypeNameFromGraphQLTypeName(namedTypeDescriptor.GraphQLTypeName)}>" + $"({idName}) ?? throw new {TypeNames.ArgumentNullException}()")); }
/// <summary> /// Adds all required deserializers of the given type descriptors properties /// </summary> protected void AddRequiredMapMethods( string propAccess, NamedTypeDescriptor namedTypeDescriptor, ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, HashSet <string> processed, bool stopAtEntityMappers = false) { if (namedTypeDescriptor.IsInterface) { foreach (var @class in namedTypeDescriptor.ImplementedBy) { AddRequiredMapMethods( propAccess, @class, classBuilder, constructorBuilder, processed); } } else { foreach (var property in namedTypeDescriptor.Properties) { AddMapMethod( propAccess, property.Type, classBuilder, constructorBuilder, processed); if (property.Type.NamedType() is NamedTypeDescriptor nt && !nt.IsLeafType() && !stopAtEntityMappers) { AddRequiredMapMethods( propAccess, nt, classBuilder, constructorBuilder, processed); } } } }
public static NameString ExtractTypeName(this NamedTypeDescriptor descriptor) { return(descriptor.IsEntityType() ? EntityTypeNameFromGraphQLTypeName(descriptor.GraphQLTypeName !) : descriptor.Name); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { var(classBuilder, constructorBuilder) = CreateClassBuilder(false); NamedTypeDescriptor descriptor = (NamedTypeDescriptor)typeDescriptor.NamedType(); // Setup class fileName = descriptor.ExtractMapperName(); classBuilder .AddImplements( TypeNames.IEntityMapper .WithGeneric(descriptor.ExtractTypeName(), descriptor.Name)) .SetName(fileName); constructorBuilder.SetTypeName(descriptor.Name); if (descriptor.ContainsEntity()) { AddConstructorAssignedField( TypeNames.IEntityStore, StoreFieldName, classBuilder, constructorBuilder); } // Define map method MethodBuilder mapMethod = MethodBuilder.New() .SetName(_mapMethodName) .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.Name) .AddParameter( ParameterBuilder.New() .SetType( descriptor.Kind == TypeKind.EntityType ? EntityTypeNameFromGraphQLTypeName(descriptor.GraphQLTypeName) : descriptor.Name) .SetName(_entityParamName)); var constructorCall = MethodCallBuilder .New() .SetMethodName($"return new {descriptor.Name}"); if (typeDescriptor is NamedTypeDescriptor namedTypeDescriptor) { foreach (PropertyDescriptor property in namedTypeDescriptor.Properties) { constructorCall.AddArgument(BuildMapMethodCall(_entityParamName, property)); } } mapMethod.AddCode(constructorCall); if (constructorBuilder.HasParameters()) { classBuilder.AddConstructor(constructorBuilder); } classBuilder.AddMethod(mapMethod); var processed = new HashSet <string>(); AddRequiredMapMethods( _entityParamName, descriptor, classBuilder, constructorBuilder, processed); CodeFileBuilder .New() .SetNamespace(descriptor.Namespace) .AddType(classBuilder) .Build(writer); }
private void AddBuildDataMethod( NamedTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var objParameter = "obj"; var buildDataMethod = MethodBuilder.New() .SetAccessModifier(AccessModifier.Private) .SetName("BuildData") .SetReturnType( $"({resultNamedType.Name}, " + $"{ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)})") .AddParameter( ParameterBuilder.New() .SetType(TypeNames.JsonElement) .SetName(objParameter)); var sessionName = "session"; buildDataMethod.AddCode( CodeLineBuilder.New() .SetLine( CodeBlockBuilder.New() .AddCode( $"using {TypeNames.IEntityUpdateSession} {sessionName} = ") .AddCode(_entityStoreFieldName + ".BeginUpdate();"))); var entityIdsName = "entityIds"; buildDataMethod.AddCode( CodeLineBuilder.New() .SetLine( $"var {entityIdsName} = new {TypeNames.HashSet}<{TypeNames.EntityId}>();")); buildDataMethod.AddEmptyLine(); foreach (PropertyDescriptor property in resultNamedType.Properties.Where(prop => prop.Type.IsEntityType())) { buildDataMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide(CodeBlockBuilder.New() .AddCode(property.Type.ToEntityIdBuilder()) .AddCode($"{property.Name.WithLowerFirstChar()}Id")) .SetRighthandSide(BuildUpdateMethodCall(property, ""))); } var resultInfoConstructor = MethodCallBuilder.New() .SetMethodName( $"new {ResultInfoNameFromTypeName(resultNamedType.ImplementedBy[0].Name)}") .SetDetermineStatement(false); foreach (PropertyDescriptor property in resultNamedType.Properties) { if (property.Type.IsEntityType()) { resultInfoConstructor.AddArgument($"{property.Name.WithLowerFirstChar()}Id"); } else { resultInfoConstructor.AddArgument(BuildUpdateMethodCall(property, "")); } } resultInfoConstructor.AddArgument(entityIdsName); resultInfoConstructor.AddArgument( $"{sessionName}.{TypeNames.IEntityUpdateSession_Version}"); buildDataMethod.AddEmptyLine(); var resultInfoName = "resultInfo"; buildDataMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {resultInfoName}") .SetRighthandSide(resultInfoConstructor)); buildDataMethod.AddEmptyLine(); buildDataMethod.AddCode( $"return ({_resultDataFactoryFieldName}" + $".Create({resultInfoName}), {resultInfoName});"); classBuilder.AddMethod(buildDataMethod); }
private void AddDataTypeDeserializerMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { if (namedTypeDescriptor.IsInterface) { methodBuilder.AddCode( "var typename = obj.Value.GetProperty(\"__typename\").GetString();"); // If the type is an interface foreach (NamedTypeDescriptor concreteType in namedTypeDescriptor.ImplementedBy) { methodBuilder.AddEmptyLine(); var ifStatement = IfBuilder.New() .SetCondition( $"typename?.Equals(\"{concreteType.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson}) ?? false"); var dataTypeName = $"global::{concreteType.Namespace}.State." + DataTypeNameFromTypeName(concreteType.GraphQLTypeName); var returnStatement = MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName(dataTypeName); returnStatement.AddArgument("typename"); foreach (PropertyDescriptor property in concreteType.Properties) { returnStatement.AddArgument( CodeBlockBuilder.New() .AddCode($"{property.Name.WithLowerFirstChar()}: ") .AddCode(BuildUpdateMethodCall(property))); } ifStatement.AddCode(returnStatement); methodBuilder.AddCode(ifStatement); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"throw new {TypeNames.NotSupportedException}();"); } else { var returnStatement = MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName(namedTypeDescriptor.Name); foreach (PropertyDescriptor property in namedTypeDescriptor.Properties) { returnStatement.AddArgument(BuildUpdateMethodCall(property)); } methodBuilder.AddCode(returnStatement); } AddRequiredDeserializeMethods( namedTypeDescriptor, classBuilder, processed); }
private void AddDataHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { method.AddParameter( ParameterBuilder.New() .SetType( $"global::{namedTypeDescriptor.Namespace}.State." + DataTypeNameFromTypeName(namedTypeDescriptor.GraphQLTypeName)) .SetName(DataParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( DataParamName, isNonNullable)); } var variableName = "returnValue"; method.AddCode($"{namedTypeDescriptor.Name} {variableName} = default!;"); method.AddEmptyLine(); if (namedTypeDescriptor.ImplementedBy.Any()) { var ifChain = InterfaceImplementeeIf(namedTypeDescriptor.ImplementedBy[0]); foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy.Skip(1)) { var singleIf = InterfaceImplementeeIf(interfaceImplementee).SkipIndents(); ifChain.AddIfElse(singleIf); } ifChain.AddElse( CodeInlineBuilder.New() .SetText($"throw new {TypeNames.NotSupportedException}();")); method.AddCode(ifChain); } IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{DataParamName}.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{DataParamName}?.__typename.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson}) ?? false"); } var constructorCall = MethodCallBuilder.New() .SetPrefix($"{variableName} = new ") .SetMethodName(interfaceImplementee.Name); foreach (PropertyDescriptor prop in interfaceImplementee.Properties) { var propAccess = $"{DataParamName}.{prop.Name}"; if (prop.Type.IsEntityType()) { constructorCall.AddArgument( BuildMapMethodCall( DataParamName, prop, true)); } else { constructorCall.AddArgument( $"{propAccess} ?? throw new {TypeNames.ArgumentNullException}()"); } } ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } method.AddCode($"return {variableName};"); AddRequiredMapMethods( DataParamName, namedTypeDescriptor, classBuilder, constructorBuilder, processed); }
private void AddEntityHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder method, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed, bool isNonNullable) { var nullabilityAdditive = "?"; if (isNonNullable) { nullabilityAdditive = ""; } method.AddParameter( ParameterBuilder.New() .SetType(TypeNames.EntityId + nullabilityAdditive) .SetName(EntityIdParamName)); if (!isNonNullable) { method.AddCode( EnsureProperNullability( EntityIdParamName, isNonNullable)); } foreach (NamedTypeDescriptor implementee in namedTypeDescriptor.ImplementedBy) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( implementee.Name, implementee.GraphQLTypeName); if (processed.Add(dataMapperName)) { var dataMapperType = $"{TypeNames.IEntityMapper}<" + $"{EntityTypeNameFromGraphQLTypeName(implementee.GraphQLTypeName)}, " + $"{implementee.Name}>"; AddConstructorAssignedField( dataMapperType, dataMapperName.ToFieldName(), classBuilder, constructorBuilder); } } foreach (NamedTypeDescriptor interfaceImplementee in namedTypeDescriptor.ImplementedBy) { method.AddCode(InterfaceImplementeeIf(interfaceImplementee)); } method.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); IfBuilder InterfaceImplementeeIf(NamedTypeDescriptor interfaceImplementee) { var dataMapperName = EntityMapperNameFromGraphQLTypeName( interfaceImplementee.Name, interfaceImplementee.GraphQLTypeName) .ToFieldName(); var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{EntityIdParamName}.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } else { ifCorrectType.SetCondition( $"{EntityIdParamName}.Value.Name.Equals(\"" + $"{interfaceImplementee.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); } MethodCallBuilder constructorCall = MethodCallBuilder.New() .SetPrefix($"return {dataMapperName}.") .SetWrapArguments() .SetMethodName(nameof(IEntityMapper <object, object> .Map)); MethodCallBuilder argument = MethodCallBuilder.New() .SetMethodName($"{StoreFieldName}.{nameof(IEntityStore.GetEntity)}") .SetDetermineStatement(false) .AddGeneric( EntityTypeNameFromGraphQLTypeName(interfaceImplementee.GraphQLTypeName)) .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value"); constructorCall.AddArgument( NullCheckBuilder.New() .SetDetermineStatement(false) .SetCondition(argument) .SetCode(ExceptionBuilder .New(TypeNames.GraphQLClientException) .SetDetermineStatement(false))); method.AddEmptyLine(); ifCorrectType.AddCode(constructorCall); return(ifCorrectType); } }
private ICode GenerateInternalMethodBody(DependencyInjectionDescriptor descriptor) { bool hasSubscriptions = descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any(); bool hasQueries = descriptor.Operations.OfType <QueryOperationDescriptor>().Any(); bool hasMutations = descriptor.Operations.OfType <MutationOperationDescriptor>().Any(); var stringBuilder = new StringBuilder(); var codeWriter = new CodeWriter(stringBuilder); stringBuilder.AppendLine(_staticCode); codeWriter.WriteComment("register connections"); if (hasSubscriptions) { stringBuilder.AppendLine(RegisterWebSocketConnection(descriptor.Name)); } if (hasQueries || hasMutations) { stringBuilder.AppendLine(RegisterHttpConnection(descriptor.Name)); } codeWriter.WriteComment("register mappers"); codeWriter.WriteLine(); foreach (var typeDescriptor in descriptor.TypeDescriptors) { if (typeDescriptor.Kind == TypeKind.EntityType && !typeDescriptor.IsInterface()) { NamedTypeDescriptor namedTypeDescriptor = (NamedTypeDescriptor)typeDescriptor.NamedType(); NameString className = namedTypeDescriptor.ExtractMapperName(); var interfaceName = TypeNames.IEntityMapper.WithGeneric( namedTypeDescriptor.ExtractTypeName(), typeDescriptor.Name); AddSingleton(codeWriter, interfaceName, className); } } codeWriter.WriteLine(); codeWriter.WriteComment("register serializers"); codeWriter.WriteLine(); foreach (var enumType in descriptor.EnumTypeDescriptor) { AddSingleton( codeWriter, TypeNames.ISerializer, EnumParserNameFromEnumName(enumType.Name)); } foreach (var serializer in _serializers) { AddSingleton( codeWriter, TypeNames.ISerializer, serializer); } foreach (var inputTypeDescriptor in descriptor.TypeDescriptors .Where(x => x.Kind is TypeKind.InputType)) { AddSingleton( codeWriter, TypeNames.ISerializer, InputValueFormatterFromType( (NamedTypeDescriptor)inputTypeDescriptor.NamedType())); } RegisterSerializerResolver().Build(codeWriter); codeWriter.WriteLine(); codeWriter.WriteComment("register operations"); foreach (var operation in descriptor.Operations) { string connectionKind = operation is SubscriptionOperationDescriptor ? TypeNames.WebSocketConnection : TypeNames.HttpConnection; NameString operationName = operation.OperationName; NameString fullName = operation.Name; NameString operationInterface = operation.ResultTypeReference.Name; // The resulttype of the operation is a NamedTypeDescriptor, that is an Interface var resultType = operation.ResultTypeReference as NamedTypeDescriptor ?? throw new ArgumentException("ResultTypeReference"); // The factories are generated based on the concrete result type, which is the // only implementee of the result type interface. var factoryName = ResultFactoryNameFromTypeName(resultType.ImplementedBy[0].Name); var builderName = ResultBuilderNameFromTypeName(operationName); stringBuilder.AppendLine( RegisterOperation( connectionKind, descriptor.Name, fullName, operationInterface, factoryName, builderName)); } stringBuilder.AppendLine( $"{TypeNames.AddSingleton.WithGeneric(descriptor.Name)}(services);"); stringBuilder.AppendLine(); stringBuilder.AppendLine("return services;"); return(CodeBlockBuilder.From(stringBuilder)); }
private static void AddProperties( ClientModel model, IMapperContext context, Dictionary <NameString, TypeDescriptorModel> typeDescriptors, Dictionary <NameString, NamedTypeDescriptor> scalarTypeDescriptors) { foreach (TypeDescriptorModel typeDescriptorModel in typeDescriptors.Values.ToList()) { var properties = new List <PropertyDescriptor>(); foreach (var field in typeDescriptorModel.TypeModel.Fields) { NamedTypeDescriptor?fieldType; INamedType namedType = field.Type.NamedType(); if (namedType.IsScalarType()) { var scalarType = (ScalarType)namedType; if (!scalarTypeDescriptors.TryGetValue( scalarType.Name, out fieldType)) { string[] runtimeTypeName = scalarType.GetRuntimeType().Split('.'); fieldType = new NamedTypeDescriptor( runtimeTypeName.Last(), string.Join( ".", runtimeTypeName.Take(runtimeTypeName.Length - 1)), false, graphQLTypeName: scalarType.Name, kind: TypeKind.LeafType); scalarTypeDescriptors.Add( scalarType.Name, fieldType); } } else if (namedType.IsEnumType()) { var enumTypeModel = model.LeafTypes .OfType <EnumTypeModel>() .First(t => t.Type == namedType); if (!scalarTypeDescriptors.TryGetValue( namedType.Name, out fieldType)) { fieldType = new NamedTypeDescriptor( enumTypeModel.Name, context.Namespace, false, graphQLTypeName: namedType.Name, serializationType: enumTypeModel.Type.GetSerializationType(), kind: TypeKind.LeafType, isEnum: true); scalarTypeDescriptors.Add( enumTypeModel.Name, fieldType); } } else { fieldType = GetFieldTypeDescriptor( model, field.SyntaxNode, field.Type.NamedType(), typeDescriptors); } properties.Add( new PropertyDescriptor( field.Name, BuildFieldType( field.Type, fieldType))); } typeDescriptorModel.NamedTypeDescriptor.Complete(properties); } }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { NamedTypeDescriptor descriptor = typeDescriptor as NamedTypeDescriptor ?? throw new InvalidOperationException(); var(classBuilder, constructorBuilder) = CreateClassBuilder(); fileName = ResultFactoryNameFromTypeName(descriptor.Name); classBuilder .SetName(fileName) .AddImplements($"{TypeNames.IOperationResultDataFactory}<{descriptor.Name}>"); constructorBuilder .SetTypeName(descriptor.Name) .SetAccessModifier(AccessModifier.Public); AddConstructorAssignedField( TypeNames.IEntityStore, StoreParamName, classBuilder, constructorBuilder); var createMethod = MethodBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetName("Create") .SetReturnType(descriptor.Name) .AddParameter("dataInfo", b => b.SetType(TypeNames.IOperationResultDataInfo)); var returnStatement = MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName(descriptor.Name); var ifHasCorrectType = IfBuilder.New() .SetCondition($"dataInfo is {ResultInfoNameFromTypeName(descriptor.Name)} info"); foreach (PropertyDescriptor property in descriptor.Properties) { returnStatement.AddArgument( BuildMapMethodCall( "info", property)); } ifHasCorrectType.AddCode(returnStatement); createMethod.AddCode(ifHasCorrectType); createMethod.AddEmptyLine(); createMethod.AddCode( $"throw new {TypeNames.ArgumentException}(\"" + $"{ResultInfoNameFromTypeName(descriptor.Name)} expected.\");"); classBuilder.AddMethod(createMethod); var processed = new HashSet <string>(); AddRequiredMapMethods( "info", descriptor, classBuilder, constructorBuilder, processed, true); CodeFileBuilder .New() .SetNamespace(descriptor.Namespace) .AddType(classBuilder) .Build(writer); }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, NamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { var entityIdVarName = "entityId"; methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide( CodeBlockBuilder.New() .AddCode(TypeNames.EntityId) .AddCode($" {entityIdVarName}")) .SetRighthandSide($"{_extractIdFieldName}({_objParamName}.Value)")); methodBuilder.AddCode($"{_entityIdsParam}.Add({entityIdVarName});"); methodBuilder.AddEmptyLine(); var entityVarName = "entity"; if (namedTypeDescriptor.IsInterface) { // If the type is an interface foreach (NamedTypeDescriptor concreteType in namedTypeDescriptor.ImplementedBy) { methodBuilder.AddEmptyLine(); var ifStatement = IfBuilder.New() .SetCondition( $"entityId.Name.Equals(\"{concreteType.GraphQLTypeName}\", " + $"{TypeNames.OrdinalStringComparisson})"); var entityTypeName = EntityTypeNameFromGraphQLTypeName(concreteType.GraphQLTypeName); WriteEntityLoader( ifStatement, entityTypeName, entityVarName, entityIdVarName); WritePropertyAssignments( ifStatement, concreteType.Properties, entityVarName); ifStatement.AddEmptyLine(); ifStatement.AddCode($"return {entityIdVarName};"); methodBuilder.AddCode(ifStatement); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"throw new {TypeNames.NotSupportedException}();"); } else { WriteEntityLoader( methodBuilder, EntityTypeNameFromGraphQLTypeName(namedTypeDescriptor.GraphQLTypeName), entityVarName, entityIdVarName); WritePropertyAssignments( methodBuilder, namedTypeDescriptor.Properties, entityVarName); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {entityIdVarName};"); } AddRequiredDeserializeMethods( namedTypeDescriptor, classBuilder, processed); }