private MethodCallBuilder CreateBuildDataStatement(ObjectTypeDescriptor concreteType) { MethodCallBuilder returnStatement = MethodCallBuilder .New() .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))); } return(returnStatement); }
protected CodeLinePragma CreateCodeLinePragma(ControlBuilder builder) { string virtualPath = builder.PageVirtualPath; int line = builder.Line; int column = 1; int generatedColumn = 1; int codeLength = -1; CodeBlockBuilder codeBlockBuilder = builder as CodeBlockBuilder; if (codeBlockBuilder != null) { column = codeBlockBuilder.Column; codeLength = codeBlockBuilder.Content.Length; if (codeBlockBuilder.BlockType == CodeBlockType.Code) { // If it's a <% ... %> block, the generated column is the same as the source generatedColumn = column; } else { // If it's a <%= ... %> block, we always generate '__o = expr' is // designer mode, so the column is fixed // generatedColumn = BaseTemplateCodeDomTreeGenerator.tempObjectVariable.Length + GetGeneratedColumnOffset(_codeDomProvider); } } return(CreateCodeLinePragma(virtualPath, line, column, generatedColumn, codeLength)); }
private static ICode GenerateMethodBody( CSharpSyntaxGeneratorSettings settings, DependencyInjectionDescriptor descriptor) => CodeBlockBuilder .New() .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));
private static void EmitInvokeCommand(CodeBlockBuilder tryBlock, TypeSet.VkHandleMethod method, Func <IEnumerable <Action <ExpressionBuilder> >, Action <ExpressionBuilder> > commandExpression, Func <TypeSet.VkMethodParam, string> argumentNameSelector, string commandResultVariable) { foreach (var fixedArgument in method.Parameters.Where(x => !string.IsNullOrEmpty(x.FixedName))) { tryBlock.EmitStatement($"fixed({fixedArgument.FixedType} {fixedArgument.FixedName} = {fixedArgument.Name})"); } var arguments = method.Parameters.Select(argumentNameSelector).Select(Variable); if (method.IsPassthroughResult) { tryBlock.EmitAssignment(Variable("result"), commandExpression(arguments)); } else if (method.HasVkResult) { tryBlock.EmitAssignment(Variable(commandResultVariable), commandExpression(arguments)); } else { tryBlock.EmitCallExpression(commandExpression(arguments)); } if (method.HasVkResult) { tryBlock.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(commandResultVariable)), ifBlock => { ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(commandResultVariable))); }); } }
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 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"); var block = CodeBlockBuilder.New(); 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 if (prop.Type.IsNonNullableType()) { if (prop.Type.NamedType() is ILeafTypeDescriptor { RuntimeType: { IsValueType: true } })
public MethodBuilder(string name, int indent) : base(name) { m_indent = indent; m_body = new CodeBlockBuilder(m_indent + 1); ReturnsVoid(); }
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)); }
protected override void Generate( InputObjectTypeDescriptor descriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { const string serializerResolver = nameof(serializerResolver); const string runtimeValue = nameof(runtimeValue); const string input = nameof(input); const string inputInfo = nameof(inputInfo); const string fields = nameof(fields); fileName = CreateInputValueFormatter(descriptor); path = Serialization; ns = descriptor.RuntimeType.NamespaceWithoutGlobal; string stateNamespace = $"{descriptor.RuntimeType.Namespace}.{State}"; string infoInterfaceType = $"{stateNamespace}.{CreateInputValueInfo(descriptor.Name)}"; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .AddImplements(TypeNames.IInputObjectFormatter); var neededSerializers = descriptor .Properties .GroupBy(x => x.Type.Name) .ToDictionary(x => x, x => x.First()); // Initialize Method CodeBlockBuilder initialize = classBuilder .AddMethod("Initialize") .SetPublic() .AddParameter(serializerResolver, x => x.SetType(TypeNames.ISerializerResolver)) .AddBody(); foreach (var property in neededSerializers.Values) { if (property.Type.GetName().Value is { } name) { var propertyName = GetFieldName(name) + "Formatter"; initialize .AddAssigment(propertyName) .AddMethodCall() .SetMethodName(serializerResolver, "GetInputValueFormatter") .AddArgument(name.AsStringToken()); classBuilder .AddField(propertyName) .SetAccessModifier(AccessModifier.Private) .SetType(TypeNames.IInputValueFormatter) .SetValue("default!"); }
protected override void Generate( CodeWriter writer, InputObjectTypeDescriptor namedTypeDescriptor, out string fileName, out string?path) { const string serializerResolver = nameof(serializerResolver); const string runtimeValue = nameof(runtimeValue); const string value = nameof(value); fileName = CreateInputValueFormatter(namedTypeDescriptor); path = Serialization; NameString typeName = namedTypeDescriptor.Name; ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .AddImplements(TypeNames.IInputObjectFormatter); var neededSerializers = namedTypeDescriptor .Properties .GroupBy(x => x.Type.Name) .ToDictionary(x => x, x => x.First()); // Initialize Method CodeBlockBuilder initialize = classBuilder .AddMethod("Initialize") .SetPublic() .AddParameter(serializerResolver, x => x.SetType(TypeNames.ISerializerResolver)) .AddBody(); foreach (var property in neededSerializers.Values) { if (property.Type.GetName().Value is { } name) { var propertyName = GetFieldName(name) + "Formatter"; initialize .AddAssigment(propertyName) .AddMethodCall() .SetMethodName( serializerResolver, "GetInputValueFormatter") .AddArgument(name.AsStringToken()); classBuilder .AddField(propertyName) .SetAccessModifier(AccessModifier.Private) .SetType(TypeNames.IInputValueFormatter) .SetValue("default!"); }
public static void EmitMarshalAction(CodeBlockBuilder codeBlock, Generation.AssignAction action, Action <ExpressionBuilder> targetExpression) { switch (action.Type) { case AssignActionType.Assign: codeBlock.EmitAssignment(targetExpression, action.ValueExpression); break; case AssignActionType.Alloc: if (action.LengthExpression != null) { codeBlock.EmitAssignment(targetExpression, Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>", action.LengthExpression))); } else { codeBlock.EmitAssignment(targetExpression, Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>"))); } break; case AssignActionType.AllocAndAssign: codeBlock.EmitAssignment(targetExpression, Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>"))); codeBlock.EmitAssignment(Deref(targetExpression), action.ValueExpression); break; case AssignActionType.MarshalToAddressOf: codeBlock.EmitCall(action.ValueExpression, "MarshalTo", AddressOf(targetExpression)); break; case AssignActionType.MarshalTo: codeBlock.EmitAssignment(targetExpression, Cast(action.MemberType + "*", StaticCall("Interop.HeapUtil", $"Allocate<{action.MemberType}>"))); codeBlock.EmitCall(action.ValueExpression, "MarshalTo", targetExpression); break; case AssignActionType.MarshalFrom: codeBlock.EmitAssignment(targetExpression, StaticCall(action.MemberType, "MarshalFrom", action.ValueExpression)); break; case AssignActionType.MarshalFromAddressOf: codeBlock.EmitAssignment(targetExpression, StaticCall(action.MemberType, "MarshalFrom", AddressOf(action.ValueExpression))); break; case AssignActionType.FixedLengthMarshalTo: codeBlock.EmitStaticCall("Interop.HeapUtil", "MarshalTo", action.ValueExpression, action.LengthExpression, targetExpression); break; } }
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); }
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 ICode FormatEntityIdBody(EntityIdFactoryDescriptor descriptor) { SwitchExpressionBuilder typeNameSwitch = SwitchExpressionBuilder .New() .SetReturn() .SetExpression($"{_entityId}.Name") .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.NotSupportedException)); foreach (var entity in descriptor.Entities) { typeNameSwitch.AddCase( entity.Name.AsStringToken(), MethodCallBuilder .Inline() .SetMethodName($"Format{entity.Name}EntityId") .AddArgument(_entityId)); } return(CodeBlockBuilder .New() .AddCode(typeNameSwitch)); }
protected CodeLinePragma CreateCodeLinePragma(ControlBuilder builder) { string pageVirtualPath = builder.PageVirtualPath; int line = builder.Line; int column = 1; int generatedColumn = 1; int codeLength = -1; CodeBlockBuilder builder2 = builder as CodeBlockBuilder; if (builder2 != null) { column = builder2.Column; codeLength = builder2.Content.Length; if (builder2.BlockType == CodeBlockType.Code) { generatedColumn = column; } else { generatedColumn = "__o".Length + GetGeneratedColumnOffset(this._codeDomProvider); } } return(this.CreateCodeLinePragma(pageVirtualPath, line, column, generatedColumn, codeLength)); }
private static ICode GenerateClientServiceProviderFactory( DependencyInjectionDescriptor descriptor) { if (descriptor.TransportProfiles.Count == 1) { return(CodeBlockBuilder .New() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_serviceCollection}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName( "ConfigureClient" + descriptor.TransportProfiles[0].Name) .AddArgument(_sp) .AddArgument(_strategy))) .AddEmptyLine() .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName("ClientServiceProvider") .SetWrapArguments() .AddArgument(MethodCallBuilder .Inline() .SetMethodName(TypeNames.BuildServiceProvider) .AddArgument(_serviceCollection)))); } SwitchExpressionBuilder switchBuilder = SwitchExpressionBuilder .New() .SetExpression(_profile) .SetDetermineStatement(false) .SetDefaultCase(ExceptionBuilder.Inline(TypeNames.ArgumentOutOfRangeException)); var enumName = CreateProfileEnumReference(descriptor); foreach (var profile in descriptor.TransportProfiles) { switchBuilder .AddCase( $"{enumName}.{profile.Name}", MethodCallBuilder .Inline() .SetMethodName("ConfigureClient" + profile.Name) .AddArgument(_sp) .AddArgument(_strategy)); } return(CodeBlockBuilder .New() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {_serviceCollection}") .SetRighthandSide(switchBuilder)) .AddEmptyLine() .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName("ClientServiceProvider") .SetWrapArguments() .AddArgument(MethodCallBuilder .Inline() .SetMethodName(TypeNames.BuildServiceProvider) .AddArgument(_serviceCollection)))); }
private static ICode RegisterOperation( CSharpSyntaxGeneratorSettings settings, string connectionKind, string operationFullName, string operationInterfaceName, string resultInterface, string factory, string resultBuilder) { return(CodeBlockBuilder .New() .AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric( TypeNames.IOperationResultDataFactory.WithGeneric(resultInterface)) .AddGeneric(factory) .AddArgument(_services)) .AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.IOperationResultDataFactory) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric( TypeNames.IOperationResultDataFactory .WithGeneric(resultInterface)) .AddArgument(_sp)))) .AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.IOperationRequestFactory) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(operationInterfaceName) .AddArgument(_sp)))) .AddCode(MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric( TypeNames.IOperationResultBuilder .WithGeneric(TypeNames.JsonDocument, resultInterface)) .AddGeneric(resultBuilder) .AddArgument(_services)) .AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.IOperationExecutor.WithGeneric(resultInterface)) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetNew() .SetMethodName(settings.IsStoreEnabled() ? TypeNames.OperationExecutor : TypeNames.StorelessOperationExecutor) .AddGeneric(TypeNames.JsonDocument) .AddGeneric(resultInterface) .AddArgument( MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(connectionKind) .AddArgument(_sp)) .AddArgument( LambdaBuilder .New() .SetCode( MethodCallBuilder .Inline() .SetMethodName( TypeNames.GetRequiredService) .AddGeneric( TypeNames.IOperationResultBuilder.WithGeneric( TypeNames.JsonDocument, resultInterface)) .AddArgument(_sp))) .If(settings.IsStoreEnabled(), x => x .AddArgument( MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(TypeNames.IOperationStore) .AddArgument(_sp)) .AddArgument(_strategy))))) .AddCode(MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(operationFullName) .AddArgument(_services)) .AddCode(MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(operationInterfaceName) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(operationFullName) .AddArgument(_sp))))); }
private static ICode GenerateInternalMethodBody( CSharpSyntaxGeneratorSettings settings, DependencyInjectionDescriptor descriptor, TransportProfile profile) { var rootNamespace = descriptor.ClientDescriptor.RuntimeType.Namespace; var hasSubscriptions = descriptor.Operations.OfType <SubscriptionOperationDescriptor>().Any(); var hasQueries = descriptor.Operations.OfType <QueryOperationDescriptor>().Any(); var hasMutations = descriptor.Operations.OfType <MutationOperationDescriptor>().Any(); CodeBlockBuilder body = CodeBlockBuilder .New() .AddCode(CreateBaseCode(settings)); var generatedConnections = new HashSet <TransportType>(); if (hasSubscriptions) { generatedConnections.Add(profile.Subscription); body.AddCode( RegisterConnection(profile.Subscription, descriptor.Name)); } if (hasQueries && !generatedConnections.Contains(profile.Query)) { generatedConnections.Add(profile.Query); body.AddCode(RegisterConnection(profile.Query, descriptor.Name)); } if (hasMutations && !generatedConnections.Contains(profile.Mutation)) { generatedConnections.Add(profile.Mutation); body.AddCode(RegisterConnection(profile.Mutation, descriptor.Name)); } body.AddEmptyLine(); foreach (var typeDescriptor in descriptor.TypeDescriptors .OfType <INamedTypeDescriptor>()) { if (typeDescriptor.Kind == TypeKind.Entity && !typeDescriptor.IsInterface()) { INamedTypeDescriptor namedTypeDescriptor = (INamedTypeDescriptor)typeDescriptor.NamedType(); NameString className = namedTypeDescriptor.ExtractMapperName(); var interfaceName = TypeNames.IEntityMapper.WithGeneric( namedTypeDescriptor.ExtractType().ToString(), $"{rootNamespace}.{typeDescriptor.RuntimeType.Name}"); body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(interfaceName) .AddGeneric($"{CreateStateNamespace(rootNamespace)}.{className}") .AddArgument(_services); } } body.AddEmptyLine(); foreach (var enumType in descriptor.EnumTypeDescriptor) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(CreateEnumParserName($"{rootNamespace}.{enumType.Name}")) .AddArgument(_services); } foreach (var serializer in _serializers) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric(serializer) .AddArgument(_services); } RuntimeTypeInfo stringTypeInfo = new RuntimeTypeInfo(TypeNames.String); foreach (var scalar in descriptor.TypeDescriptors.OfType <ScalarTypeDescriptor>()) { if (scalar.RuntimeType.Equals(stringTypeInfo) && scalar.SerializationType.Equals(stringTypeInfo) && !BuiltInScalarNames.IsBuiltInScalar(scalar.Name)) { body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddArgument(_services) .AddArgument(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.StringSerializer) .AddArgument(scalar.Name.AsStringToken())); } } foreach (var inputTypeDescriptor in descriptor.TypeDescriptors .Where(x => x.Kind is TypeKind.Input)) { var formatter = CreateInputValueFormatter( (InputObjectTypeDescriptor)inputTypeDescriptor.NamedType()); body.AddMethodCall() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializer) .AddGeneric($"{rootNamespace}.{formatter}") .AddArgument(_services); } body.AddCode(RegisterSerializerResolver()); body.AddEmptyLine(); foreach (var operation in descriptor.Operations) { if (!(operation.ResultTypeReference is InterfaceTypeDescriptor typeDescriptor)) { continue; } TransportType operationKind = operation switch { SubscriptionOperationDescriptor => profile.Subscription, QueryOperationDescriptor => profile.Query, MutationOperationDescriptor => profile.Mutation, _ => throw ThrowHelper.DependencyInjection_InvalidOperationKind(operation) }; string connectionKind = operationKind switch { TransportType.Http => TypeNames.IHttpConnection, TransportType.WebSocket => TypeNames.IWebSocketConnection, TransportType.InMemory => TypeNames.IInMemoryConnection, { } v => throw ThrowHelper.DependencyInjection_InvalidTransportType(v) }; string operationName = operation.Name; string fullName = operation.RuntimeType.ToString(); string operationInterfaceName = operation.InterfaceType.ToString(); string resultInterface = typeDescriptor.RuntimeType.ToString(); // The factories are generated based on the concrete result type, which is the // only implementee of the result type interface. var factoryName = CreateResultFactoryName( typeDescriptor.ImplementedBy.First().RuntimeType.Name); var builderName = CreateResultBuilderName(operationName); body.AddCode( RegisterOperation( settings, connectionKind, fullName, operationInterfaceName, resultInterface, $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{factoryName}", $"{CreateStateNamespace(operation.RuntimeType.Namespace)}.{builderName}")); } if (settings.IsStoreEnabled()) { body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.IEntityIdSerializer) .AddGeneric(descriptor.EntityIdFactoryDescriptor.Type.ToString()) .AddArgument(_services)); } body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString()) .AddArgument(_services)); body.AddCode( MethodCallBuilder .New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(descriptor.ClientDescriptor.InterfaceType.ToString()) .AddArgument(_services) .AddArgument(LambdaBuilder .New() .AddArgument(_sp) .SetCode(MethodCallBuilder .Inline() .SetMethodName(TypeNames.GetRequiredService) .AddGeneric(descriptor.ClientDescriptor.RuntimeType.ToString()) .AddArgument(_sp)))); body.AddLine($"return {_services};"); return(body); }
private static ICode GenerateClientServiceProviderFactory( DependencyInjectionDescriptor descriptor) { CodeBlockBuilder codeBuilder = CodeBlockBuilder.New(); if (descriptor.TransportProfiles.Count == 1) { return(codeBuilder .AddCode( MethodCallBuilder .New() .SetMethodName("ConfigureClient" + descriptor.TransportProfiles[0].Name) .AddArgument(_sp) .AddArgument(_serviceCollection) .AddArgument(_strategy)) .AddEmptyLine() .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName("ClientServiceProvider") .SetWrapArguments() .AddArgument(MethodCallBuilder .Inline() .SetMethodName(TypeNames.BuildServiceProvider) .AddArgument(_serviceCollection)))); } IfBuilder ifProfile = IfBuilder.New(); var enumName = CreateProfileEnumReference(descriptor); for (var index = 0; index < descriptor.TransportProfiles.Count; index++) { TransportProfile profile = descriptor.TransportProfiles[index]; IfBuilder currentIf = ifProfile; if (index != 0) { currentIf = IfBuilder.New(); ifProfile.AddIfElse(currentIf); } currentIf .SetCondition($"{_profile} == {enumName}.{profile.Name}") .AddCode( MethodCallBuilder .New() .SetMethodName("ConfigureClient" + profile.Name) .AddArgument(_sp) .AddArgument(_serviceCollection) .AddArgument(_strategy)); } return(codeBuilder .AddCode(ifProfile) .AddEmptyLine() .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName("ClientServiceProvider") .SetWrapArguments() .AddArgument(MethodCallBuilder .Inline() .SetMethodName(TypeNames.BuildServiceProvider) .AddArgument(_serviceCollection)))); }
private static ICode GenerateEntityHandlerIfClause( ObjectTypeDescriptor objectTypeDescriptor, bool isNonNullable) { var dataMapperName = GetFieldName( CreateEntityMapperName( objectTypeDescriptor.RuntimeType.Name, objectTypeDescriptor.Name)); MethodCallBuilder constructorCall = MethodCallBuilder .New() .SetReturn() .SetWrapArguments() .SetMethodName(dataMapperName, "Map"); MethodCallBuilder argument = MethodCallBuilder .Inline() .SetMethodName(_snapshot, "GetEntity") .AddGeneric(CreateEntityType( objectTypeDescriptor.Name, objectTypeDescriptor.RuntimeType.NamespaceWithoutGlobal) .ToString()) .AddArgument(isNonNullable ? _entityId : $"{_entityId}.Value"); constructorCall.AddArgument( NullCheckBuilder .New() .SetDetermineStatement(false) .SetCondition(argument) .SetCode(ExceptionBuilder.Inline(TypeNames.GraphQLClientException))); IfBuilder ifCorrectType = IfBuilder .New() .AddCode(constructorCall) .SetCondition( MethodCallBuilder .Inline() .SetMethodName( isNonNullable ? new[] { _entityId, "Name", nameof(string.Equals) } : new[] { _entityId, "Value", "Name", nameof(string.Equals) }) .AddArgument(objectTypeDescriptor.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison)); return(CodeBlockBuilder .New() .AddEmptyLine() .AddCode(ifCorrectType)); }
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)); }
private void AddArrayHandler( CSharpSyntaxGeneratorSettings settings, ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder .AddParameter(_list) .SetType(listTypeDescriptor.ToStateTypeReference()); if (settings.IsStoreEnabled()) { methodBuilder .AddParameter(_snapshot) .SetType(TypeNames.IEntityStoreSnapshot); } var listVarName = GetParameterName(listTypeDescriptor.Name) + "s"; methodBuilder.AddCode(EnsureProperNullability(_list, isNonNullable)); methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder .New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode( listTypeDescriptor.InnerType.ToTypeReference().SkipTrailingSpace()) .AddCode(">") .AddCode("()"))); methodBuilder.AddEmptyLine(); ForEachBuilder forEachBuilder = ForEachBuilder .New() .SetLoopHeader( CodeBlockBuilder .New() .AddCode(listTypeDescriptor.InnerType.ToStateTypeReference()) .AddCode($"{_child} in {_list}")) .AddCode( MethodCallBuilder .New() .SetMethodName(listVarName, nameof(List <object> .Add)) .AddArgument(MethodCallBuilder .Inline() .SetMethodName(MapMethodNameFromTypeName(listTypeDescriptor.InnerType)) .AddArgument(_child) .If(settings.IsStoreEnabled(), x => x.AddArgument(_snapshot)))); methodBuilder .AddCode(forEachBuilder) .AddEmptyLine() .AddCode($"return {listVarName};"); AddMapMethod( settings, listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
private ICode FormatSpecificEntityIdBody(EntityIdDescriptor entity) { var body = CodeBlockBuilder .New(); body.AddAssigment($"using var {_writer}") .SetRighthandSide( MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ArrayWriter)); body.AddAssigment($"using var {_jsonWriter}") .SetRighthandSide( MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.Utf8JsonWriter) .AddArgument(_writer) .AddArgument(_options)); body.AddMethodCall() .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteStartObject)); body.AddEmptyLine(); body.AddMethodCall() .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteString)) .AddArgument(WellKnownNames.TypeName.AsStringToken()) .AddArgument($"{_entityId}.Name"); body.AddEmptyLine(); if (entity.Fields.Count == 1) { ScalarEntityIdDescriptor?field = entity.Fields[0]; body.AddMethodCall() .SetMethodName(_jsonWriter, GetWriteMethod(field)) .AddArgument(field.Name.AsStringToken()) .AddArgument($"({field.SerializationType}){_entityId}.Value"); } else { body.AddAssigment($"var {_entityIdValues}") .SetRighthandSide(CodeBlockBuilder .New() .AddCode("(") .AddCode(TupleBuilder .New() .AddMemberRange( entity.Fields.Select(x => x.SerializationType.ToString()))) .AddCode($"){_entityId}.Value")); body.AddEmptyLine(); for (var index = 0; index < entity.Fields.Count; index++) { ScalarEntityIdDescriptor field = entity.Fields[index]; body.AddMethodCall() .SetMethodName(_jsonWriter, GetWriteMethod(field)) .AddArgument(field.Name.AsStringToken()) .AddArgument($"{_entityIdValues}.Item{index + 1}"); body.AddEmptyLine(); } } body.AddMethodCall() .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.WriteEndObject)); body.AddMethodCall() .SetMethodName(_jsonWriter, nameof(Utf8JsonWriter.Flush)); body.AddEmptyLine(); body.AddMethodCall() .SetReturn() .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString)) .AddArgument(MethodCallBuilder.Inline().SetMethodName(_writer, "GetInternalBuffer")) .AddArgument("0") .AddArgument($"{_writer}.Length"); return(body); }
private void AddEntityDataTypeDeserializerToMethod( 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))))); foreach (ObjectTypeDescriptor concreteType in interfaceTypeDescriptor.ImplementedBy) { ICode builder; if (concreteType.IsEntity()) { builder = CodeBlockBuilder .New() .AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.EntityId} {_entityId}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_idSerializer, "Parse") .AddArgument($"{_obj}.Value"))) .AddCode(CreateUpdateEntityStatement(concreteType) .AddCode(MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(TypeNames.EntityIdOrData) .AddArgument(_entityId))); } else { builder = MethodCallBuilder .New() .SetNew() .SetReturn() .SetMethodName(TypeNames.EntityIdOrData) .AddArgument(CreateBuildDataStatement(concreteType) .SetDetermineStatement(false) .SetNew()); } methodBuilder .AddEmptyLine() .AddCode(IfBuilder .New() .SetCondition( $"typename?.Equals(\"{concreteType.Name}\", " + $"{TypeNames.OrdinalStringComparison}) ?? false") .AddCode(builder)); } methodBuilder .AddEmptyLine() .AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); }
private static void EmitActions(CodeBlockBuilder body, List <MethodAction> actions) { foreach (var action in actions.OfType <DeclarationAction>()) { body.EmitVariableDeclaration(action.MemberType, action.MemberName, Default(action.MemberType)); } foreach (var action in actions.OrderBy(x => x.Priority)) { if (action is AssignAction assignAction) { if (assignAction.IsLoop) { void BuildAssignBlock(CodeBlockBuilder ifBlock) { var fieldPointerName = assignAction.FieldPointerName ?? "fieldPointer"; if (assignAction.IsArray) { ifBlock.EmitVariableDeclaration("var", fieldPointerName, NewArray(assignAction.MemberType, Cast("uint", assignAction.LengthExpression))); } else { string allocationType = assignAction.MemberType.EndsWith("*") ? "IntPtr" : assignAction.MemberType; ifBlock.EmitVariableDeclaration("var", fieldPointerName, Cast(assignAction.MemberType + "*", Call(StaticCall("Interop.HeapUtil", $"AllocateAndClear<{allocationType}>", assignAction.LengthExpression), "ToPointer"))); } ifBlock.EmitForLoop(init => init.EmitVariableDeclaration("int", assignAction.IndexName, Literal(0)), LessThan(Variable(assignAction.IndexName), Cast("uint", assignAction.LengthExpression)), after => after.EmitStatement(assignAction.IndexName + "++"), loop => { EmitMarshalAction(loop, assignAction, Index(Variable(fieldPointerName), Variable(assignAction.IndexName))); }); ifBlock.EmitAssignment(assignAction.TargetExpression, Variable(fieldPointerName)); } if (assignAction.NullCheckExpression != null) { body.EmitIfBlock(assignAction.NullCheckExpression, BuildAssignBlock, elseBlock => { elseBlock.EmitAssignment(assignAction.TargetExpression, Null); }); } else { BuildAssignBlock(body); } } else { EmitMarshalAction(body, assignAction, assignAction.TargetExpression); } } else if (action is InvokeAction invokeAction) { var paramNames = (invokeAction.Parameters ?? Enumerable.Empty <Action <ExpressionBuilder> >().ToArray()); Action <ExpressionBuilder> invokeExpression = null; if (invokeAction.LookupDelegate) { if (invokeAction.DelegateName != null) { body.EmitVariableDeclaration(invokeAction.DelegateName, "commandDelegate", Call(Variable("commandCache"), $"GetCommandDelegate<{invokeAction.DelegateName}>", Literal(invokeAction.MethodName), Literal(invokeAction.LookupScope))); } invokeExpression = DelegateCall(Variable("commandDelegate"), paramNames); } else if (invokeAction.TypeName == null) { invokeExpression = Call(This, invokeAction.MethodName, paramNames); } else { invokeExpression = StaticCall(invokeAction.TypeName, invokeAction.MethodName, paramNames); } if (invokeAction.ReturnName != null) { if (invokeAction.ReturnType != null) { body.EmitVariableDeclaration(invokeAction.ReturnType, invokeAction.ReturnName, invokeExpression); } else { body.EmitAssignment(Variable(invokeAction.ReturnName), invokeExpression); } } else { body.EmitCallExpression(invokeExpression); } } else if (action is OptionalAction optionalAction) { if (optionalAction.ElseActions.Any()) { body.EmitIfBlock(optionalAction.CheckExpression, ifBlock => EmitActions(ifBlock, optionalAction.Actions), elseBlock => EmitActions(elseBlock, optionalAction.ElseActions)); } else { body.EmitIfBlock(optionalAction.CheckExpression, ifBlock => EmitActions(ifBlock, optionalAction.Actions)); } } else if (action is ValidateAction validationAction) { body.EmitIfBlock(StaticCall("SharpVkException", "IsError", Variable(validationAction.VariableName)), ifBlock => { ifBlock.EmitThrow(StaticCall("SharpVkException", "Create", Variable(validationAction.VariableName))); }); } } }
protected override void Generate(EntityIdFactoryDescriptor descriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { fileName = descriptor.Name; path = State; ns = descriptor.Namespace; ClassBuilder classBuilder = ClassBuilder .New() .SetAccessModifier(AccessModifier.Public) .AddImplements(TypeNames.IEntityIdSerializer) .SetName(fileName); classBuilder .AddField(_options) .SetStatic() .SetReadOnly() .SetType(TypeNames.JsonWriterOptions) .SetValue(CodeBlockBuilder .New() .AddCode(MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.JsonWriterOptions)) .AddCode(CodeInlineBuilder.From("{ Indented = false }"))); classBuilder .AddMethod("Parse") .SetAccessModifier(AccessModifier.Public) .SetReturnType(TypeNames.EntityId) .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement)) .AddCode(ParseEntityIdBody(descriptor)); classBuilder .AddMethod("Format") .SetAccessModifier(AccessModifier.Public) .SetReturnType(TypeNames.String) .AddParameter(_entityId, x => x.SetType(TypeNames.EntityId)) .AddCode(FormatEntityIdBody(descriptor)); foreach (var entity in descriptor.Entities) { classBuilder .AddMethod($"Parse{entity.Name}EntityId") .SetAccessModifier(AccessModifier.Private) .SetReturnType(TypeNames.EntityId) .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement)) .AddParameter(_type, x => x.SetType(TypeNames.String)) .AddCode(ParseSpecificEntityIdBody(entity)); classBuilder .AddMethod($"Format{entity.Name}EntityId") .SetAccessModifier(AccessModifier.Private) .SetReturnType(TypeNames.String) .AddParameter(_entityId, x => x.SetType(TypeNames.EntityId)) .AddCode(FormatSpecificEntityIdBody(entity)); } classBuilder.Build(writer); }