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"))))));
public static MethodCallBuilder AddMethodCall(this CodeBlockBuilder builder) { var methodCallBuilder = MethodCallBuilder.New(); builder.AddCode(methodCallBuilder); return(methodCallBuilder); }
private static ICode RegisterSerializerResolver() => MethodCallBuilder.New() .SetMethodName(TypeNames.AddSingleton) .AddGeneric(TypeNames.ISerializerResolver) .AddArgument("services") .AddArgument(LambdaBuilder.New() .AddArgument("sp") .SetCode( MethodCallBuilder.New() .SetPrefix("new ") .SetMethodName(TypeNames.SerializerResolver) .SetDetermineStatement(false) .SetWrapArguments() .AddArgument(MethodCallBuilder.New() .SetMethodName(TypeNames.Concat) .SetDetermineStatement(false) .AddArgument( MethodCallBuilder.New() .SetMethodName(TypeNames.GetRequiredService) .SetDetermineStatement(false) .SetWrapArguments() .AddGeneric( TypeNames.IEnumerable.WithGeneric(TypeNames .ISerializer)) .AddArgument("parentServices")) .AddArgument(MethodCallBuilder.New() .SetMethodName(TypeNames.GetRequiredService) .SetDetermineStatement(false) .SetWrapArguments() .AddGeneric( TypeNames.IEnumerable.WithGeneric(TypeNames.ISerializer)) .AddArgument("sp")))));
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)))));
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 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 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)); }
private static AssignmentBuilder CreateDataError( string exception = "ex") { string dict = TypeNames.Dictionary.WithGeneric( TypeNames.String, TypeNames.Object.MakeNullable()); string body = "response.Body?.RootElement.ToString()"; MethodCallBuilder createClientError = MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ClientError) .AddArgument($"{exception}.Message") .AddArgument($"exception: {exception}") .AddArgument($"extensions: new {dict} {{ {{ \"body\", {body} }} }}"); return(AssignmentBuilder.New() .SetLefthandSide("errors") .SetRighthandSide( ArrayBuilder.New() .SetDetermineStatement(false) .SetType(TypeNames.IClientError) .AddAssignment(createClientError))); }
private static 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 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); }
private void AddDataTypeDeserializerMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, ComplexTypeDescriptor complexTypeDescriptor, HashSet <string> processed) { if (complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) { AddInterfaceDataTypeDeserializerToMethod(methodBuilder, interfaceTypeDescriptor); } else { MethodCallBuilder returnStatement = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(complexTypeDescriptor.Name); foreach (PropertyDescriptor property in complexTypeDescriptor.Properties) { returnStatement.AddArgument(BuildUpdateMethodCall(property)); } methodBuilder.AddCode(returnStatement); } AddRequiredDeserializeMethods(complexTypeDescriptor, classBuilder, processed); }
private IfBuilder GenerateDataInterfaceIfClause( ObjectTypeDescriptor objectTypeDescriptor, bool isNonNullable, string variableName) { ICode ifCondition = MethodCallBuilder .Inline() .SetMethodName( _dataParameterName.MakeNullable(!isNonNullable), WellKnownNames.TypeName, nameof(string.Equals)) .AddArgument(objectTypeDescriptor.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison); if (!isNonNullable) { ifCondition = NullCheckBuilder .New() .SetCondition(ifCondition) .SetSingleLine() .SetDetermineStatement(false) .SetCode("false"); } MethodCallBuilder constructorCall = MethodCallBuilder .Inline() .SetNew() .SetMethodName(objectTypeDescriptor.RuntimeType.Name); foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties) { var propAccess = $"{_dataParameterName}.{prop.Name}"; if (prop.Type.IsEntityType() || prop.Type.IsDataType()) { constructorCall.AddArgument(BuildMapMethodCall(_dataParameterName, prop, true)); } else if (prop.Type.IsNullableType()) { constructorCall.AddArgument(propAccess); } else { constructorCall .AddArgument( NullCheckBuilder .Inline() .SetCondition(propAccess) .SetCode(ExceptionBuilder.Inline(TypeNames.ArgumentNullException))); } } return(IfBuilder .New() .SetCondition(ifCondition) .AddCode(AssignmentBuilder .New() .SetLefthandSide(variableName) .SetRighthandSide(constructorCall))); }
private void AddArrayHandler( ClassBuilder classBuilder, ConstructorBuilder constructorBuilder, MethodBuilder methodBuilder, ListTypeDescriptor listTypeDescriptor, HashSet <string> processed, bool isNonNullable) { methodBuilder.AddParameter( ParameterBuilder.New() .SetType(listTypeDescriptor.ToEntityIdBuilder()) .SetName(ListParamName)); var listVarName = listTypeDescriptor.Name.WithLowerFirstChar() + "s"; if (!isNonNullable) { methodBuilder.AddCode(EnsureProperNullability(ListParamName, isNonNullable)); } methodBuilder.AddCode( AssignmentBuilder.New() .SetLefthandSide($"var {listVarName}") .SetRighthandSide( CodeBlockBuilder.New() .AddCode("new ") .AddCode(TypeNames.List) .AddCode("<") .AddCode( listTypeDescriptor.InnerType.ToBuilder() .SkipTrailingSpace()) .AddCode(">") .AddCode("()"))); methodBuilder.AddEmptyLine(); var loopbuilder = ForEachBuilder.New() .SetLoopHeader( CodeBlockBuilder.New() .AddCode(listTypeDescriptor.InnerType.ToEntityIdBuilder()) .AddCode($"child in {ListParamName}")) .AddCode( MethodCallBuilder.New() .SetPrefix($"{listVarName}.") .SetMethodName("Add") .AddArgument( BuildMapMethodCall( listTypeDescriptor.InnerType, "child"))); methodBuilder.AddCode(loopbuilder); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {listVarName};"); AddMapMethod( listVarName, listTypeDescriptor.InnerType, classBuilder, constructorBuilder, processed); }
private 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)); }
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( CodeWriter writer, OperationDescriptor descriptor, out string fileName) { var documentName = CreateDocumentTypeName(descriptor.Name); fileName = documentName; string operationKind = descriptor switch { MutationOperationDescriptor => "Mutation", QueryOperationDescriptor => "Query", SubscriptionOperationDescriptor => "Subscription", _ => throw new ArgumentOutOfRangeException(nameof(descriptor)) }; ClassBuilder classBuilder = ClassBuilder .New() .AddImplements(TypeNames.IDocument) .SetName(fileName); classBuilder .AddConstructor() .SetPrivate(); classBuilder .AddProperty("Instance") .SetStatic() .SetType(documentName) .SetValue($"new {documentName}()"); classBuilder .AddProperty("Kind") .SetType(TypeNames.OperationKind) .AsLambda($"{TypeNames.OperationKind}.{operationKind}"); classBuilder .AddProperty("Body") .SetType(TypeNames.IReadOnlySpan.WithGeneric(TypeNames.Byte)) .AsLambda(GetByteArray(descriptor.BodyString)); classBuilder .AddMethod("ToString") .SetPublic() .SetOverride() .SetReturnType(TypeNames.String) .AddCode(MethodCallBuilder .New() .SetReturn() .SetMethodName(TypeNames.EncodingUtf8, nameof(Encoding.UTF8.GetString)) .AddArgument("Body")); CodeFileBuilder .New() .SetNamespace(descriptor.Namespace) .AddType(classBuilder) .Build(writer); }
public void WorksWithMixtureOfGenericAndConcreteParams() { var methodCall = MethodCallBuilder .Create <Example, IEnumerable <string>, int, string, double>((e, a, b, c) => e.OverloadedGeneric(a, b, c)) .SetArguments(1, "two", 3.2); ExecuteAndAssert(new [] { "1", "two", "3.2" }, methodCall); }
public void WorksWhenNotAllArgsAreUsed() { var methodCall = MethodCallBuilder .Create <Example, string, double, int, string>((e, y, x, z) => e.SingleArg(z)) .SetArguments(3.5, 1, "single"); ExecuteAndAssert("single", methodCall); }
public void WorksWithGenericClass() { var methodCall = MethodCallBuilder .Create <GenericExample <int>, int, int>((ge, i) => ge.Echo(i)) .SetArgument(532); ExecuteAndAssert(532, methodCall); }
public void WorksWhenThereAreOverloads() { var methodCall = MethodCallBuilder .Create <Example, string, string, string>((e, x, y) => e.SingleArg(x, y)) .SetArguments("first", "second"); ExecuteAndAssert("firstsecond", methodCall); }
public void WorksWhenThereAreGenericOverloads() { var methodCall = MethodCallBuilder .Create <Example, IEnumerable <string>, string, int>((e, x, y) => e.OverloadedGeneric(x, y)) .SetArguments("one", 2); ExecuteAndAssert(new [] { "one", "2" }, methodCall); }
public void WorksWithParametersOutOfOrder() { var methodCall = MethodCallBuilder .Create <Example, IEnumerable <string>, double, int, string>((e, y, x, z) => e.WithThreeArgs(x, y, z)) .SetArguments(3.5, 1, "four"); ExecuteAndAssert(new [] { "1", "3.5", "four" }, methodCall); }
public void WorksWithGenericArgs() { var methodCall = MethodCallBuilder .Create <Example, IEnumerable <string>, string, int>((e, a, b) => e.WithGenericArgs(a, b)) .SetArguments("first thing", 21); ExecuteAndAssert(new [] { "first thing", "21" }, methodCall); }
public static CodeBlockBuilder AddMethodCall( this CodeBlockBuilder builder, Action <MethodCallBuilder> configure) { var methodCallBuilder = new MethodCallBuilder(); configure(methodCallBuilder); return(builder.AddCode(methodCallBuilder)); }
private void AddBuildMethod( InterfaceTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var responseParameterName = "response"; var buildMethod = MethodBuilder .New() .SetAccessModifier(AccessModifier.Public) .SetName("Build") .SetReturnType( TypeReferenceBuilder.New() .SetName(TypeNames.IOperationResult) .AddGeneric(resultNamedType.RuntimeType.Name)) .AddParameter( ParameterBuilder.New() .SetType( TypeReferenceBuilder.New() .SetName(TypeNames.Response) .AddGeneric(TypeNames.JsonDocument) .SetName(TypeNames.Response)) .SetName(responseParameterName)); var concreteResultType = CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name); buildMethod.AddCode( AssignmentBuilder.New() .SetLefthandSide( $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " + "Info)? data") .SetRighthandSide("null")); buildMethod.AddEmptyLine(); buildMethod.AddCode( IfBuilder.New() .SetCondition( ConditionBuilder.New() .Set("response.Body is not null") .And("response.Body.RootElement.TryGetProperty(\"data\"," + $" out {TypeNames.JsonElement} obj)")) .AddCode("data = BuildData(obj);")); buildMethod.AddEmptyLine(); buildMethod.AddCode( MethodCallBuilder.New() .SetPrefix("return new ") .SetMethodName( TypeNames.OperationResult.WithGeneric(resultNamedType.RuntimeType.Name)) .AddArgument("data?.Result") .AddArgument("data?.Info") .AddArgument(_resultDataFactoryFieldName) .AddArgument("null")); classBuilder.AddMethod(buildMethod); }
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 IfBuilder BuildTryGetEntityIf(RuntimeTypeInfo entityType) { return(IfBuilder .New() .SetCondition(MethodCallBuilder .Inline() .SetMethodName(_session, "CurrentSnapshot", "TryGetEntity") .AddArgument(_entityId) .AddOutArgument(_entity, entityType.ToString()))); }
public static MethodCallBuilder AddArgumentRange( this MethodCallBuilder builder, IEnumerable <string> arguments) { foreach (var argument in arguments) { builder.AddArgument(argument); } return(builder); }