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 AddArrayHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder .AddParameter(_list) .SetType(listTypeDescriptor.ToEntityIdBuilder()); var listVarName = GetParameterName(listTypeDescriptor.Name) + "s"; if (!isNonNullable) { methodBuilder.AddCode(EnsureProperNullability(_list, 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(); ForEachBuilder forEachBuilder = ForEachBuilder .New() .SetLoopHeader( CodeBlockBuilder .New() .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder()) .AddCode($"{_child} in {_list}")) .AddCode( MethodCallBuilder .New() .SetMethodName(listVarName, nameof(List <object> .Add)) .AddArgument(MethodCallBuilder .Inline() .SetMethodName(MapMethodNameFromTypeName(listTypeDescriptor.InnerType)) .AddArgument(_child))); methodBuilder .AddCode(forEachBuilder) .AddEmptyLine() .AddCode($"return {listVarName};"); AddMapMethod( listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
protected override void Generate( CodeWriter writer, OperationDescriptor descriptor, out string fileName) { var(classBuilder, constructorBuilder) = CreateClassBuilder(); fileName = DocumentTypeNameFromOperationName(descriptor.Name); classBuilder .AddImplements(TypeNames.IDocument) .SetName(fileName); constructorBuilder.SetAccessModifier(AccessModifier.Private); classBuilder.AddField( FieldBuilder.New() .SetStatic() .SetConst() .SetType(TypeNames.String) .SetName("_bodyString") .SetValue($"@\"{descriptor.BodyString}\"", true)); classBuilder.AddField( FieldBuilder.New() .SetStatic() .SetReadOnly() .SetType("byte[]") .SetName("_body") .SetValue($"{TypeNames.EncodingUtf8}.GetBytes(_bodyString)")); string operationKind; switch (descriptor) { case MutationOperationDescriptor mutationOperationDescriptor: operationKind = "Mutation"; break; case QueryOperationDescriptor queryOperationDescriptor: operationKind = "Query"; break; case SubscriptionOperationDescriptor subscriptionOperationDescriptor: operationKind = "Subscription"; break; default: throw new ArgumentOutOfRangeException(nameof(descriptor)); } classBuilder.AddProperty( PropertyBuilder.New() .SetStatic() .SetType(fileName) .SetName("Instance") .SetValue($"new {fileName}()")); classBuilder.AddProperty( PropertyBuilder.New() .SetType(TypeNames.OperationKind) .SetName("Kind").AsLambda($"{TypeNames.OperationKind}.{operationKind}")); classBuilder.AddProperty( PropertyBuilder.New() .SetType($"{TypeNames.IReadOnlySpan}<byte>") .SetName("Body").AsLambda("_body")); classBuilder.AddMethod( MethodBuilder.New() .SetAccessModifier(AccessModifier.Public) .SetReturnType("override string") .SetName("ToString") .AddCode("return _bodyString;")); CodeFileBuilder .New() .SetNamespace(descriptor.Namespace) .AddType(classBuilder) .Build(writer); }
public ClassBuilder AddMethod(MethodBuilder method) { _methods.Add(method); return(this); }
private void AddDataTypeDeserializerMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, ComplexTypeDescriptor complexTypeDescriptor, HashSet <string> processed) { if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { methodBuilder.AddCode( "var typename = obj.Value.GetProperty(\"__typename\").GetString();"); // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { methodBuilder.AddEmptyLine(); var ifStatement = IfBuilder.New() .SetCondition( $"typename?.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison}) ?? false"); var dataTypeName = $"{concreteType.RuntimeType.Namespace}.State." + CreateDataTypeName(concreteType.Name); var returnStatement = MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName(dataTypeName); returnStatement.AddArgument("typename"); foreach (PropertyDescriptor property in concreteType.Properties) { returnStatement.AddArgument( CodeBlockBuilder.New() .AddCode($"{GetParameterName(property.Name)}: ") .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(complexTypeDescriptor.Name); foreach (PropertyDescriptor property in complexTypeDescriptor.Properties) { returnStatement.AddArgument(BuildUpdateMethodCall(property)); } methodBuilder.AddCode(returnStatement); } AddRequiredDeserializeMethods( complexTypeDescriptor, classBuilder, processed); }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor 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 is InterfaceTypeDescriptor interfaceTypeDescriptor) { // If the type is an interface foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { methodBuilder.AddEmptyLine(); var ifStatement = IfBuilder.New() .SetCondition( $"entityId.Name.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison})"); var entityTypeName = CreateEntityTypeName(concreteType.Name); 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 if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { WriteEntityLoader( methodBuilder, CreateEntityTypeName(namedTypeDescriptor.Name), entityVarName, entityIdVarName); WritePropertyAssignments( methodBuilder, complexTypeDescriptor.Properties, entityVarName); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {entityIdVarName};"); } AddRequiredDeserializeMethods( namedTypeDescriptor, classBuilder, processed); }
protected override void Generate( CodeWriter writer, ITypeDescriptor typeDescriptor, out string fileName) { // Setup class ComplexTypeDescriptor descriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result entity mapper can only be generated for complex types"); fileName = descriptor.ExtractMapperName(); ClassBuilder classBuilder = ClassBuilder .New() .AddImplements( TypeNames.IEntityMapper .WithGeneric(descriptor.ExtractTypeName(), descriptor.RuntimeType.Name)) .SetName(fileName); ConstructorBuilder constructorBuilder = ConstructorBuilder .New() .SetTypeName(descriptor.Name); if (descriptor.ContainsEntity()) { AddConstructorAssignedField( TypeNames.IEntityStore, StoreFieldName, 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.EntityType ? CreateEntityTypeName(descriptor.Name) : descriptor.Name) .SetName(_entity)); MethodCallBuilder constructorCall = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(descriptor.RuntimeType.Name); if (typeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { foreach (PropertyDescriptor property in complexTypeDescriptor.Properties) { constructorCall.AddArgument(BuildMapMethodCall(_entity, property)); } } mapMethod.AddCode(constructorCall); if (constructorBuilder.HasParameters()) { classBuilder.AddConstructor(constructorBuilder); } classBuilder.AddMethod(mapMethod); AddRequiredMapMethods( _entity, descriptor, classBuilder, constructorBuilder, new HashSet <string>()); CodeFileBuilder .New() .SetNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal) .AddType(classBuilder) .Build(writer); }