예제 #1
0
 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"))))));
        private MethodCallBuilder CreateResultInfoMethodCall(
            CSharpSyntaxGeneratorSettings settings,
            InterfaceTypeDescriptor resultNamedType,
            string concreteType)
        {
            MethodCallBuilder resultInfoConstructor = MethodCallBuilder
                                                      .Inline()
                                                      .SetMethodName($"new {concreteType}");

            foreach (PropertyDescriptor property in resultNamedType.Properties)
            {
                if (property.Type.IsOrContainsEntity())
                {
                    resultInfoConstructor.AddArgument($"{GetParameterName(property.Name)}Id");
                }
                else
                {
                    resultInfoConstructor.AddArgument(BuildUpdateMethodCall(property));
                }
            }

            if (settings.IsStoreEnabled())
            {
                resultInfoConstructor
                .AddArgument(_entityIds)
                .AddArgument($"{_snapshot}.Version");
            }

            return(resultInfoConstructor);
        }
        private ICode CreateEntityConstructorCall(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool assignDefault)
        {
            var propertyLookup = objectTypeDescriptor.Properties.ToDictionary(x => x.Name.Value);

            MethodCallBuilder newEntity = MethodCallBuilder
                                          .Inline()
                                          .SetNew()
                                          .SetMethodName(objectTypeDescriptor.EntityTypeDescriptor.RuntimeType.ToString());

            foreach (PropertyDescriptor property in
                     objectTypeDescriptor.EntityTypeDescriptor.Properties.Values)
            {
                if (propertyLookup.TryGetValue(property.Name.Value, out var ownProperty))
                {
                    newEntity.AddArgument(BuildUpdateMethodCall(ownProperty));
                }
                else if (assignDefault)
                {
                    newEntity.AddArgument("default!");
                }
                else
                {
                    newEntity.AddArgument($"{_entity}.{property.Name}");
                }
            }

            return(MethodCallBuilder
                   .New()
                   .SetMethodName(_session, "SetEntity")
                   .AddArgument(_entityId)
                   .AddArgument(newEntity));
        }
예제 #4
0
 private static ICode RegisterSerializerResolver() =>
 MethodCallBuilder
 .New()
 .SetMethodName(TypeNames.AddSingleton)
 .AddGeneric(TypeNames.ISerializerResolver)
 .AddArgument(_services)
 .AddArgument(LambdaBuilder
              .New()
              .AddArgument(_sp)
              .SetCode(
                  MethodCallBuilder
                  .Inline()
                  .SetNew()
                  .SetMethodName(TypeNames.SerializerResolver)
                  .SetWrapArguments()
                  .AddArgument(MethodCallBuilder
                               .Inline()
                               .SetMethodName(TypeNames.Concat)
                               .AddArgument(
                                   MethodCallBuilder
                                   .Inline()
                                   .SetMethodName(TypeNames.GetRequiredService)
                                   .SetWrapArguments()
                                   .AddGeneric(
                                       TypeNames.IEnumerable.WithGeneric(
                                           TypeNames.ISerializer))
                                   .AddArgument(_parentServices))
                               .AddArgument(MethodCallBuilder
                                            .Inline()
                                            .SetMethodName(TypeNames.GetRequiredService)
                                            .SetWrapArguments()
                                            .AddGeneric(
                                                TypeNames.IEnumerable.WithGeneric(TypeNames.ISerializer))
                                            .AddArgument(_sp)))));
예제 #5
0
 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()))))));
예제 #6
0
        private static MethodBuilder BuildEqualsMethod(
            string typeName,
            IReadOnlyList <PropertyDescriptor> properties)
        {
            const string other = nameof(other);

            ConditionBuilder equalCondition =
                ConditionBuilder
                .New()
                .SetReturn()
                .SetDetermineStatement();

            if (properties.Count == 0)
            {
                equalCondition.And("true");
            }
            else
            {
                foreach (PropertyDescriptor property in properties)
                {
                    equalCondition.And(ConditionBuilder
                                       .New()
                                       .Set(BuildPropertyComparison(property.Type, property.Name)));
                }
            }

            return(MethodBuilder
                   .New()
                   .SetName(nameof(IEquatable <object> .Equals))
                   .SetPublic()
                   .SetInheritance(Inheritance.Virtual)
                   .SetReturnType(TypeNames.Boolean)
                   .AddParameter(other, x => x.SetType(typeName.MakeNullable()))
                   .AddCode(CodeBlockBuilder
                            .New()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("null")
                                                   .AddArgument(other))
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("this")
                                                   .AddArgument(other))
                                     .AddCode("return true;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition($"{other}.GetType() != GetType()")
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddCode(equalCondition)));
        }
        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 }
                    })
        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 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 static ICode GenerateEntityHandlerIfClause(
            ObjectTypeDescriptor objectTypeDescriptor,
            bool isNonNullable)
        {
            var dataMapperName =
                GetFieldName(
                    CreateEntityMapperName(
                        objectTypeDescriptor.RuntimeType.Name,
                        objectTypeDescriptor.Name));

            MethodCallBuilder constructorCall = MethodCallBuilder
                                                .New()
                                                .SetReturn()
                                                .SetWrapArguments()
                                                .SetMethodName(dataMapperName, nameof(IEntityMapper <object, object> .Map));

            MethodCallBuilder argument = MethodCallBuilder
                                         .Inline()
                                         .SetMethodName(StoreFieldName, nameof(IEntityStore.GetEntity))
                                         .AddGeneric(CreateEntityTypeName(objectTypeDescriptor.Name))
                                         .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,
                nameof(EntityId.Name),
                nameof(string.Equals)
            }
                                : new[]
            {
                _entityId,
                nameof(Nullable <EntityId> .Value),
                nameof(EntityId.Name),
                nameof(string.Equals)
            })
                .AddArgument(objectTypeDescriptor.Name.AsStringToken())
                .AddArgument(TypeNames.OrdinalStringComparison));

            return(CodeBlockBuilder
                   .New()
                   .AddEmptyLine()
                   .AddCode(ifCorrectType));
        }
예제 #11
0
        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 IfBuilder BuildTryGetEntityIf(RuntimeTypeInfo entityType)
 {
     return(IfBuilder
            .New()
            .SetCondition(MethodCallBuilder
                          .Inline()
                          .SetMethodName(_session, "CurrentSnapshot", "TryGetEntity")
                          .AddArgument(_entityId)
                          .AddOutArgument(_entity, entityType.ToString())));
 }
        public static MethodCallBuilder Chain(
            this MethodCallBuilder builder,
            Action <MethodCallBuilder> configure)
        {
            var chainedMethod = MethodCallBuilder.Inline();

            configure(chainedMethod);
            builder.AddChainedCode(chainedMethod);
            return(builder);
        }
        private MethodCallBuilder BuildUpdateMethodCall(PropertyDescriptor property)
        {
            MethodCallBuilder propertyAccessor = MethodCallBuilder
                                                 .Inline()
                                                 .SetMethodName(TypeNames.GetPropertyOrNull)
                                                 .AddArgument(_obj)
                                                 .AddArgument(property.FieldName.AsStringToken());

            return(BuildUpdateMethodCall(property.Type, propertyAccessor).SetWrapArguments());
        }
        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);
        }
예제 #16
0
 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)));
 }
        private void AddScalarTypeDeserializerMethod(
            MethodBuilder methodBuilder,
            ILeafTypeDescriptor namedType)
        {
            string deserializeMethod = JsonUtils.GetParseMethod(namedType.SerializationType);

            methodBuilder.AddCode(
                MethodCallBuilder
                .New()
                .SetReturn()
                .SetMethodName(GetFieldName(namedType.Name) + "Parser", "Parse")
                .AddArgument(MethodCallBuilder
                             .Inline()
                             .SetMethodName(_obj, nameof(Nullable <JsonElement> .Value), deserializeMethod)
                             .SetNullForgiving()));
        }
예제 #18
0
 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 MethodCallBuilder BuildUpdateMethodCall(
            ITypeDescriptor property,
            ICode argument)
        {
            MethodCallBuilder deserializeMethodCaller = MethodCallBuilder
                                                        .Inline()
                                                        .SetMethodName(DeserializerMethodNameFromTypeName(property));

            deserializeMethodCaller.AddArgument(argument);

            if (property.IsEntityType() || property.ContainsEntity())
            {
                deserializeMethodCaller.AddArgument(_entityIds);
            }

            return(deserializeMethodCaller);
        }
예제 #20
0
 private static ICode ForwardSingletonToClientServiceProvider(string generic) =>
 MethodCallBuilder
 .New()
 .SetMethodName(TypeNames.AddSingleton)
 .AddArgument(_services)
 .AddArgument(LambdaBuilder
              .New()
              .AddArgument(_sp)
              .SetCode(MethodCallBuilder
                       .Inline()
                       .SetMethodName(TypeNames.GetRequiredService)
                       .SetWrapArguments()
                       .AddArgument(MethodCallBuilder
                                    .Inline()
                                    .SetMethodName(TypeNames.GetRequiredService)
                                    .AddGeneric("ClientServiceProvider")
                                    .AddArgument(_sp))
                       .AddGeneric(generic)));
예제 #21
0
        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();
                }
예제 #22
0
 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));
예제 #23
0
        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);
            }
        }
    }
예제 #24
0
        private static ICode BuildPropertyComparison(
            ITypeDescriptor type,
            string propertyName)
        {
            const string other = nameof(other);

            return(BuildPropertyInternal(type, true));

            ICode BuildPropertyInternal(
                ITypeDescriptor currentType,
                bool isNullable)
            {
                return(currentType switch
                {
                    NonNullTypeDescriptor d =>
                    BuildPropertyInternal(d.InnerType, false),
                    ILeafTypeDescriptor d when d.SerializationType.IsValueType =>
                    CodeInlineBuilder
                    .New()
                    .SetText($"{propertyName} == {other}.{propertyName}"),
                    INamedTypeDescriptor when isNullable =>
                    ConditionBuilder
                    .New()
                    .Set($"({propertyName} is null && {other}.{propertyName} is null) ||" +
                         $"{propertyName} != null && {propertyName}.{nameof(Equals)}(" +
                         $"{other}.{propertyName})"),
                    INamedTypeDescriptor =>
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(propertyName, nameof(Equals))
                    .AddArgument($"{other}.{propertyName}"),
                    ListTypeDescriptor =>
                    MethodCallBuilder
                    .Inline()
                    .SetMethodName(TypeNames.SequenceEqual)
                    .AddArgument(propertyName)
                    .AddArgument($"{other}.{propertyName}"),
                    _ => throw new ArgumentOutOfRangeException()
                });
            }
        private void AddScalarTypeDeserializerMethod(
            MethodBuilder methodBuilder,
            ILeafTypeDescriptor namedType)
        {
            string deserializeMethod = namedType.SerializationType.ToString() switch
            {
                TypeNames.String => nameof(JsonElement.GetString),
                TypeNames.Uri => nameof(JsonElement.GetString),
                TypeNames.Byte => nameof(JsonElement.GetByte),
                TypeNames.ByteArray => nameof(JsonElement.GetBytesFromBase64),
                TypeNames.Int16 => nameof(JsonElement.GetInt16),
                TypeNames.Int32 => nameof(JsonElement.GetInt32),
                TypeNames.Int64 => nameof(JsonElement.GetInt64),
                TypeNames.UInt16 => nameof(JsonElement.GetUInt16),
                TypeNames.UInt32 => nameof(JsonElement.GetUInt32),
                TypeNames.UInt64 => nameof(JsonElement.GetUInt64),
                TypeNames.Single => nameof(JsonElement.GetSingle),
                TypeNames.Double => nameof(JsonElement.GetDouble),
                TypeNames.Decimal => nameof(JsonElement.GetDecimal),
                TypeNames.DateTimeOffset => nameof(JsonElement.GetString),
                TypeNames.DateTime => nameof(JsonElement.GetString),
                TypeNames.TimeSpan => nameof(JsonElement.GetString),
                TypeNames.Boolean => nameof(JsonElement.GetBoolean),
                TypeNames.Guid => nameof(JsonElement.GetGuid),
                _ => throw new NotSupportedException("Serialization format not supported.")
            };

            methodBuilder.AddCode(
                MethodCallBuilder
                .New()
                .SetReturn()
                .SetMethodName(
                    GetFieldName(namedType.Name) + "Parser",
                    nameof(ILeafValueParser <object, object> .Parse))
                .AddArgument(MethodCallBuilder
                             .Inline()
                             .SetMethodName(_obj, nameof(Nullable <JsonElement> .Value), deserializeMethod)
                             .SetNullForgiving()));
        }
    }
예제 #26
0
        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));
        }
예제 #27
0
        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));
        }
예제 #28
0
        private static MethodBuilder BuildObjectEqualsMethod(string typeName)
        {
            const string obj = nameof(obj);

            return(MethodBuilder
                   .New()
                   .SetName(nameof(IEquatable <object> .Equals))
                   .SetPublic()
                   .SetOverride()
                   .SetReturnType(TypeNames.Boolean)
                   .AddParameter(obj, x => x.SetType(TypeNames.Object.MakeNullable()))
                   .AddCode(CodeBlockBuilder
                            .New()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("null")
                                                   .AddArgument(obj))
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition(MethodCallBuilder
                                                   .Inline()
                                                   .SetMethodName(nameof(ReferenceEquals))
                                                   .AddArgument("this")
                                                   .AddArgument(obj))
                                     .AddCode("return true;"))
                            .AddEmptyLine()
                            .AddCode(IfBuilder
                                     .New()
                                     .SetCondition($"{obj}.GetType() != GetType()")
                                     .AddCode("return false;"))
                            .AddEmptyLine()
                            .AddLine($"return Equals(({typeName}){obj});")));
        }
        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)));
        }
예제 #30
0
        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));
        }