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 void GenerateIfForEachImplementedBy( MethodBuilder method, ComplexTypeDescriptor complexTypeDescriptor, Func<ObjectTypeDescriptor, IfBuilder> generator) { if (!(complexTypeDescriptor is InterfaceTypeDescriptor interfaceTypeDescriptor) || !interfaceTypeDescriptor.ImplementedBy.Any()) { return; } IEnumerable<ObjectTypeDescriptor> dataTypes = interfaceTypeDescriptor.ImplementedBy.Where(x => x.IsData()); IfBuilder ifChain = generator(dataTypes.First()); foreach (ObjectTypeDescriptor objectTypeDescriptor in dataTypes.Skip(1)) { ifChain.AddIfElse(generator(objectTypeDescriptor).SkipIndents()); } ifChain.AddElse(ExceptionBuilder.New(TypeNames.NotSupportedException)); method.AddCode(ifChain); }
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 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 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 Rule GetStartRule(DeltinScript deltinScript) { var condition = new Condition( Element.Part <V_CountOf>(Path.GetVariable()), Operators.GreaterThan, 0 ); Element eventPlayer = new V_EventPlayer(); Element eventPlayerPos = Element.Part <V_PositionOf>(eventPlayer); TranslateRule rule = new TranslateRule(deltinScript, Constants.INTERNAL_ELEMENT + "Pathfinder: Move", RuleEvent.OngoingPlayer); IfBuilder isBetween = new IfBuilder(rule.ActionSet, Element.Part <V_And>( Element.Part <V_CountOf>(Path.GetVariable()) >= 2, IsBetween(eventPlayerPos, NextPosition(eventPlayer), PositionAt(eventPlayer, 1)) ) ); isBetween.Setup(); rule.ActionSet.AddAction(Next()); isBetween.Finish(); rule.ActionSet.AddAction(ArrayBuilder <Element> .Build ( LastUpdate.SetVariable(new V_TotalTimeElapsed()), DistanceToNext.SetVariable(Element.Part <V_DistanceBetween>(Element.Part <V_PositionOf>(new V_EventPlayer()), NextPosition(new V_EventPlayer()))), // Element.Part<A_StartFacing>( // new V_EventPlayer(), // Element.Part<V_DirectionTowards>( // new V_EyePosition(), // NextPosition() // ), // new V_Number(700), // EnumData.GetEnumValue(Relative.ToWorld), // EnumData.GetEnumValue(FacingRev.DirectionAndTurnRate) // ), // Move to the next node. Element.Part <A_StartThrottleInDirection>( new V_EventPlayer(), Element.Part <V_DirectionTowards>( new V_EyePosition(), NextPosition(new V_EventPlayer()) // Because of ThrottleRev this will be reevaluated so 'Start Throttle In Direction' only needs to run once. ), new V_Number(1), EnumData.GetEnumValue(Relative.ToWorld), EnumData.GetEnumValue(ThrottleBehavior.ReplaceExistingThrottle), EnumData.GetEnumValue(ThrottleRev.DirectionAndMagnitude) ) )); var result = rule.GetRule(); result.Conditions = new Condition[] { condition }; return(result); }
public static CodeBlockBuilder AddIf( this CodeBlockBuilder builder, Action <IfBuilder> configure) { var ifBuilder = IfBuilder.New(); configure(ifBuilder); return(builder.AddCode(ifBuilder)); }
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); }
private IfBuilder BuildTryGetEntityIf(RuntimeTypeInfo entityType) { return(IfBuilder .New() .SetCondition(MethodCallBuilder .Inline() .SetMethodName(_session, "CurrentSnapshot", "TryGetEntity") .AddArgument(_entityId) .AddOutArgument(_entity, entityType.ToString()))); }
private static ICode GenerateEntityHandlerIfClause( ObjectTypeDescriptor objectTypeDescriptor, bool isNonNullable) { var dataMapperName = GetFieldName( CreateEntityMapperName( objectTypeDescriptor.RuntimeType.Name, objectTypeDescriptor.Name)); var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{EntityIdParamName}.Name.Equals(\"" + $"{objectTypeDescriptor.Name}\", " + $"{TypeNames.OrdinalStringComparison})"); } else { ifCorrectType.SetCondition( $"{EntityIdParamName}.Value.Name.Equals(\"" + $"{objectTypeDescriptor.Name}\", " + $"{TypeNames.OrdinalStringComparison})"); } MethodCallBuilder constructorCall = MethodCallBuilder.New() .SetPrefix($"return {dataMapperName}.") .SetWrapArguments() .SetMethodName(nameof(IEntityMapper <object, object> .Map)); MethodCallBuilder argument = MethodCallBuilder.New() .SetMethodName($"{StoreFieldName}.{nameof(IEntityStore.GetEntity)}") .SetDetermineStatement(false) .AddGeneric(CreateEntityTypeName(objectTypeDescriptor.Name)) .AddArgument(isNonNullable ? EntityIdParamName : $"{EntityIdParamName}.Value"); constructorCall.AddArgument( NullCheckBuilder.New() .SetDetermineStatement(false) .SetCondition(argument) .SetCode(ExceptionBuilder .New(TypeNames.GraphQLClientException) .SetDetermineStatement(false))); ifCorrectType.AddCode(constructorCall); return(CodeBlockBuilder.New() .AddEmptyLine() .AddCode(ifCorrectType)); }
private void AddDeserializeMethod( ITypeDescriptor typeReference, ClassBuilder classBuilder, HashSet <string> processed) { string methodName = DeserializerMethodNameFromTypeName(typeReference); if (processed.Add(methodName)) { MethodBuilder methodBuilder = classBuilder .AddMethod() .SetPrivate() .SetReturnType(typeReference.ToStateTypeReference()) .SetName(methodName); if (typeReference.IsOrContainsEntityType()) { methodBuilder .AddParameter(_session, x => x.SetType(TypeNames.IEntityStoreUpdateSession)) .AddParameter(_obj, x => x.SetType(TypeNames.JsonElement.MakeNullable())) .AddParameter( _entityIds, x => x.SetType(TypeNames.ISet.WithGeneric(TypeNames.EntityId))); } else { methodBuilder .AddParameter(_obj) .SetType(TypeNames.JsonElement.MakeNullable()); } IfBuilder jsonElementNullCheck = IfBuilder .New() .SetCondition($"!{_obj}.HasValue") .AddCode( typeReference.IsNonNullableType() ? ExceptionBuilder.New(TypeNames.ArgumentNullException) : CodeLineBuilder.From("return null;")); methodBuilder .AddCode(jsonElementNullCheck) .AddEmptyLine(); AddDeserializeMethodBody(classBuilder, methodBuilder, typeReference, processed); } }
private IfBuilder GenerateDataInterfaceIfClause( ObjectTypeDescriptor objectTypeDescriptor, bool isNonNullable, string variableName) { var ifCorrectType = IfBuilder.New(); if (isNonNullable) { ifCorrectType.SetCondition( $"{_dataParameterName}.__typename.Equals(\"" + $"{objectTypeDescriptor.Name}\", " + $"{TypeNames.OrdinalStringComparison})"); } else { ifCorrectType.SetCondition( $"{_dataParameterName}?.__typename.Equals(\"" + $"{objectTypeDescriptor.Name}\", " + $"{TypeNames.OrdinalStringComparison}) ?? false"); } var constructorCall = MethodCallBuilder.New() .SetPrefix($"{variableName} = new ") .SetMethodName(objectTypeDescriptor.RuntimeType.Name); foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties) { var propAccess = $"{_dataParameterName}.{prop.Name}"; if (prop.Type.IsEntityType()) { constructorCall.AddArgument(BuildMapMethodCall(_dataParameterName, prop, true)); } else { constructorCall.AddArgument( $"{propAccess} ?? throw new {TypeNames.ArgumentNullException}()"); } } ifCorrectType.AddCode(constructorCall); return(ifCorrectType); }
public BlockStatement Process(DecompilationContext context, BlockStatement body) { this.methodContext = context.get_MethodContext(); V_0 = context.get_MethodContext().get_Method().get_Module().get_TypeSystem(); this.logicalBuilderContext = new LogicalFlowBuilderContext(context.get_MethodContext().get_ControlFlowGraph()); this.cfgBlockSplitter = new CFGBlockSplitter(this.logicalBuilderContext); this.conditionBuilder = new ConditionBuilder(this.logicalBuilderContext, V_0); this.loopBuilder = new LoopBuilder(this.logicalBuilderContext, V_0); this.switchBuilder = new SwitchBuilder(this.logicalBuilderContext); this.ifBuilder = new IfBuilder(this.logicalBuilderContext, this.methodContext.get_Method().get_Module().get_TypeSystem()); this.followNodeDeterminator = new FollowNodeDeterminator(V_0); this.yieldGuardedBlocksBuilder = new YieldGuardedBlocksBuilder(this.logicalBuilderContext, context); this.GetMaxIndexOfBlock(); this.InitializeTheBlock(); this.guardedBlocksBuilder = new GuardedBlocksBuilder(this.logicalBuilderContext); context.get_MethodContext().set_LogicalConstructsTree(this.BuildLogicalConstructTree()); context.get_MethodContext().set_LogicalConstructsContext(this.logicalBuilderContext); return(body); }
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); } } }
private CodeBlockBuilder EnsureProperNullability( string propertyName = _objParamName, bool isNonNullType = false) { var ifBuilder = IfBuilder .New() .SetCondition( ConditionBuilder.New() .Set($"!{propertyName}.HasValue")); ifBuilder.AddCode( isNonNullType ? $"throw new {TypeNames.ArgumentNullException}();" : "return null;"); var codeBuilder = CodeBlockBuilder.New() .AddCode(ifBuilder) .AddEmptyLine(); return(codeBuilder); }
private IfBuilder GenerateComplexDataInterfaceIfClause( ObjectTypeDescriptor objectTypeDescriptor, string variableName) { var ifCorrectType = IfBuilder.New(); 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. // TODO : state namespace should be available here! var dataTypeName = new RuntimeTypeInfo( CreateDataTypeName(objectTypeDescriptor.Name), $"{objectTypeDescriptor.RuntimeType.Namespace}.State"); ifCorrectType.SetCondition( $"{_dataParameterName} is {dataTypeName} {matchedTypeName}"); var constructorCall = MethodCallBuilder.New() .SetPrefix($"{variableName} = new ") .SetMethodName(objectTypeDescriptor.RuntimeType.ToString()); foreach (PropertyDescriptor prop in objectTypeDescriptor.Properties) { var propAccess = $"{matchedTypeName}.{prop.Name}"; if (prop.Type.IsEntityType()) { constructorCall.AddArgument( BuildMapMethodCall( matchedTypeName, prop)); } else { constructorCall.AddArgument(propAccess); } } return(ifCorrectType.AddCode(constructorCall)); }
private TryCatchBuilder CreateBuildDataSerialization() { return(TryCatchBuilder .New() .AddTryCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set("response.Body != null")) .AddCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set("response.Body.RootElement.TryGetProperty(" + $"\"data\", out {TypeNames.JsonElement} " + "dataElement) && dataElement.ValueKind == " + $"{TypeNames.JsonValueKind}.Object")) .AddCode("data = BuildData(dataElement);")) .AddCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set( "response.Body.RootElement.TryGetProperty(" + $"\"errors\", out {TypeNames.JsonElement} " + "errorsElement)")) .AddCode($"errors = {TypeNames.ParseError}(errorsElement);"))) .AddCatchBlock( CatchBlockBuilder .New() .SetExceptionVariable("ex") .AddCode(CreateDataError()))); }
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)); }
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))); }
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});"))); }
public BlockStatement Process(DecompilationContext context, BlockStatement body) { this.methodContext = context.MethodContext; TypeSystem typeSystem = context.MethodContext.Method.Module.TypeSystem; logicalBuilderContext = new LogicalFlowBuilderContext(context.MethodContext.ControlFlowGraph); cfgBlockSplitter = new CFGBlockSplitter(logicalBuilderContext); conditionBuilder = new ConditionBuilder(logicalBuilderContext, typeSystem); loopBuilder = new LoopBuilder(logicalBuilderContext, typeSystem); switchBuilder = new SwitchBuilder(logicalBuilderContext); ifBuilder = new IfBuilder(logicalBuilderContext, methodContext.Method.Module.TypeSystem); followNodeDeterminator = new FollowNodeDeterminator(typeSystem); yieldGuardedBlocksBuilder = new YieldGuardedBlocksBuilder(logicalBuilderContext, context); GetMaxIndexOfBlock(); InitializeTheBlock(); guardedBlocksBuilder = new GuardedBlocksBuilder(logicalBuilderContext); context.MethodContext.LogicalConstructsTree = BuildLogicalConstructTree(); context.MethodContext.LogicalConstructsContext = logicalBuilderContext; return(body); }
private IfBuilder CreateUpdateEntityStatement( ObjectTypeDescriptor concreteType) { IfBuilder ifStatement = IfBuilder .New() .SetCondition( MethodCallBuilder .Inline() .SetMethodName(_entityId, "Name", nameof(string.Equals)) .AddArgument(concreteType.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison)); RuntimeTypeInfo entityTypeName = CreateEntityType( concreteType.Name, concreteType.RuntimeType.NamespaceWithoutGlobal); IfBuilder ifBuilder = BuildTryGetEntityIf(entityTypeName) .AddCode(CreateEntityConstructorCall(concreteType, false)) .AddElse(CreateEntityConstructorCall(concreteType, true)); return(ifStatement .AddCode(ifBuilder) .AddEmptyLine()); }
private void AddBuildMethod( InterfaceTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var buildMethod = classBuilder .AddMethod() .SetAccessModifier(AccessModifier.Public) .SetName("Build") .SetReturnType( TypeReferenceBuilder .New() .SetName(TypeNames.IOperationResult) .AddGeneric(resultNamedType.RuntimeType.Name)); buildMethod .AddParameter(_response) .SetType(TypeNames.Response.WithGeneric(TypeNames.JsonDocument)); var concreteResultType = CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name); // (IGetFooResult Result, GetFooResultInfo Info)? data = null; buildMethod.AddCode( AssignmentBuilder .New() .SetLefthandSide( $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " + "Info)? data") .SetRighthandSide("null")); // IReadOnlyList<IClientError>? errors = null; buildMethod.AddCode( AssignmentBuilder .New() .SetLefthandSide( TypeNames.IReadOnlyList .WithGeneric(TypeNames.IClientError) .MakeNullable() + " errors") .SetRighthandSide("null")); buildMethod.AddEmptyLine(); buildMethod.AddEmptyLine(); buildMethod.AddCode( IfBuilder.New() .SetCondition("response.Exception is null") .AddCode(CreateBuildDataSerialization()) .AddElse(CreateDataError("response.Exception")) ); buildMethod.AddEmptyLine(); buildMethod.AddCode( MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(TypeNames.OperationResult) .AddGeneric(resultNamedType.RuntimeType.Name) .AddArgument("data?.Result") .AddArgument("data?.Info") .AddArgument(_resultDataFactory) .AddArgument("errors")); }
private void AddUpdateEntityMethod( ClassBuilder classBuilder, MethodBuilder methodBuilder, INamedTypeDescriptor namedTypeDescriptor, HashSet <string> processed) { methodBuilder.AddCode( AssignmentBuilder .New() .SetLefthandSide($"{TypeNames.EntityId} {_entityId}") .SetRighthandSide( MethodCallBuilder .Inline() .SetMethodName(_extractId) .AddArgument($"{_obj}.{nameof(Nullable<EntityId>.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) { IfBuilder ifStatement = IfBuilder .New() .SetCondition( MethodCallBuilder .Inline() .SetMethodName( _entityId, nameof(EntityId.Name), nameof(string.Equals)) .AddArgument(concreteType.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison)); var entityTypeName = CreateEntityTypeName(concreteType.Name); WriteEntityLoader( ifStatement, entityTypeName); WritePropertyAssignments( ifStatement, concreteType.Properties); ifStatement .AddEmptyLine() .AddCode($"return {_entityId};"); methodBuilder .AddEmptyLine() .AddCode(ifStatement); } methodBuilder.AddEmptyLine(); methodBuilder.AddCode(ExceptionBuilder.New(TypeNames.NotSupportedException)); } else if (namedTypeDescriptor is ComplexTypeDescriptor complexTypeDescriptor) { WriteEntityLoader(methodBuilder, CreateEntityTypeName(namedTypeDescriptor.Name)); WritePropertyAssignments(methodBuilder, complexTypeDescriptor.Properties); methodBuilder.AddEmptyLine(); methodBuilder.AddCode($"return {_entityId};"); } AddRequiredDeserializeMethods(namedTypeDescriptor, classBuilder, processed); }
protected override void GenerateContext() { var contextNamespace = ContextNamespace(); var contextClassName = ContextClassName(); Action <FileBuilder> generateContextInline = (FileBuilder fileBuilder) => { if (!Options.OutputToSingleFile) { var filePath = $"{Options.OutputDir}{Path.DirectorySeparatorChar}{Options.ContextName}.generated.cs"; fileBuilder.Path(filePath); } fileBuilder.Using("Microsoft.EntityFrameworkCore"); fileBuilder.Namespace(contextNamespace, true, ns => { ns.Class(contextClassName, true, contextClass => { contextClass.Partial(true).Inherits(Options.ContextBaseClassName); TablesToGenerate.ForEach(table => { var tableClassFullName = TableClassFullName(table); var tableNamePlural = Pluralize(table.Name); contextClass.Property(tableNamePlural, true, dbSetProp => { dbSetProp.Virtual(true).Type($"DbSet<{tableClassFullName}>"); }); }); // empty constructor. contextClass.Constructor(c => c.Class(contextClass)); // constructor with options. contextClass.Constructor(c => c .Class(contextClass) .Parameter(p => p.Type($"DbContextOptions<{contextClassName}>").Name("options")) .BaseParameter("options") ); // override On Configuring contextClass.Method(m => { m .AccessModifier(AccessModifiers.Protected) .Override(true) .ReturnType("void") .Name("OnConfiguring") .Parameter(p => p.Type("DbContextOptionsBuilder").Name("optionsBuilder")); if (Options.AddConnectionStringOnGenerate) { m.Add(() => { return(IfBuilder.Create() .RawCondition(c => c.Condition("!optionsBuilder.IsConfigured")) .Add(RawLineBuilder.Create( "#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.") .NoEndOfLine()) .Add(UseDatabaseEngineConnectionStringLine())); }); } }); // model creating. contextClass.Method(m => { m .AccessModifier(AccessModifiers.Protected) .Override(true) .ReturnType("void") .Name("OnModelCreating") .Parameter(p => p.Type("ModelBuilder").Name("modelBuilder")); TablesToGenerate.ForEach(table => { AddFluentToMethod(m, table); }); SequenceToGenerate.ForEach(sequence => { var dataType = DataTypeResolver.ResolveType(sequence); var outputType = dataType.GetOutputType(); m.RawLine($"modelBuilder.HasSequence<{outputType}>(\"{sequence.Name}\").StartsAt({sequence.StartAt}).IncrementsBy({sequence.IncrementsBy})"); }); }); }); }); }; if (Options.OutputToSingleFile) { GenerationContext.SingleFile(fb => generateContextInline(fb)); } else { GenerationContext.FileIfPathIsSet(fb => generateContextInline(fb)); } }
private void AddBuildMethod( InterfaceTypeDescriptor resultNamedType, ClassBuilder classBuilder) { var buildMethod = classBuilder .AddMethod() .SetAccessModifier(AccessModifier.Public) .SetName("Build") .SetReturnType( TypeReferenceBuilder .New() .SetName(TypeNames.IOperationResult) .AddGeneric(resultNamedType.RuntimeType.Name)); buildMethod .AddParameter(_response) .SetType(TypeNames.Response.WithGeneric(TypeNames.JsonDocument)); var concreteResultType = CreateResultInfoName(resultNamedType.ImplementedBy.First().RuntimeType.Name); buildMethod.AddCode( AssignmentBuilder .New() .SetLefthandSide( $"({resultNamedType.RuntimeType.Name} Result, {concreteResultType} " + "Info)? data") .SetRighthandSide("null")); buildMethod.AddCode( AssignmentBuilder .New() .SetLefthandSide( TypeNames.IReadOnlyList .WithGeneric(TypeNames.IClientError) .MakeNullable() + " errors") .SetRighthandSide("null")); buildMethod.AddEmptyLine(); buildMethod.AddCode( TryCatchBuilder .New() .AddTryCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set("response.Body != null")) .AddCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set("response.Body.RootElement.TryGetProperty(" + $"\"data\", out {TypeNames.JsonElement} " + "dataElement) && dataElement.ValueKind == " + $"{TypeNames.JsonValueKind}.Object")) .AddCode("data = BuildData(dataElement);")) .AddCode( IfBuilder .New() .SetCondition( ConditionBuilder .New() .Set( "response.Body.RootElement.TryGetProperty(" + $"\"errors\", out {TypeNames.JsonElement} " + "errorsElement)")) .AddCode($"errors = {TypeNames.ParseError}(errorsElement);"))) .AddCatchBlock( CatchBlockBuilder .New() .SetExceptionVariable("ex") .AddCode( AssignmentBuilder.New() .SetLefthandSide("errors") .SetRighthandSide( ArrayBuilder.New() .SetDetermineStatement(false) .SetType(TypeNames.IClientError) .AddAssigment( MethodCallBuilder .Inline() .SetNew() .SetMethodName(TypeNames.ClientError) .AddArgument("ex.Message") .AddArgument("exception: ex")))))); buildMethod.AddEmptyLine(); buildMethod.AddCode( MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(TypeNames.OperationResult) .AddGeneric(resultNamedType.RuntimeType.Name) .AddArgument("data?.Result") .AddArgument("data?.Info") .AddArgument(_resultDataFactory) .AddArgument("errors")); }
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)))); }
public void Get() { var firstNode = ClosestNodeToPosition(Nodes, position); Assign(); current = actionSet.VarCollection.Assign("Dijkstra: Current", actionSet.IsGlobal, true); IndexReference distances = actionSet.VarCollection.Assign("Dijkstra: Distances", actionSet.IsGlobal, false); unvisited = actionSet.VarCollection.Assign("Dijkstra: Unvisited", actionSet.IsGlobal, false); IndexReference connectedSegments = actionSet.VarCollection.Assign("Dijkstra: Connected Segments", actionSet.IsGlobal, true); IndexReference neighborIndex = actionSet.VarCollection.Assign("Dijkstra: Neighbor Index", actionSet.IsGlobal, true); IndexReference neighborDistance = actionSet.VarCollection.Assign("Dijkstra: Distance", actionSet.IsGlobal, true); parentArray = actionSet.VarCollection.Assign("Dijkstra: Parent Array", actionSet.IsGlobal, false); // Set the current variable as the first node. actionSet.AddAction(current.SetVariable(firstNode)); SetInitialDistances(actionSet, distances, (Element)current.GetVariable()); SetInitialUnvisited(actionSet, Nodes, unvisited); WhileBuilder whileBuilder = new WhileBuilder(actionSet, LoopCondition()); whileBuilder.Setup(); // Get neighboring indexes actionSet.AddAction(connectedSegments.SetVariable(GetConnectedSegments( Nodes, Segments, (Element)current.GetVariable(), reversed ))); // Loop through neighboring indexes ForeachBuilder forBuilder = new ForeachBuilder(actionSet, connectedSegments.GetVariable()); forBuilder.Setup(); actionSet.AddAction(ArrayBuilder <Element> .Build( // Get the index from the segment data neighborIndex.SetVariable( Element.TernaryConditional( new V_Compare( current.GetVariable(), Operators.NotEqual, Node1(forBuilder.IndexValue) ), Node1(forBuilder.IndexValue), Node2(forBuilder.IndexValue) ) ), // Get the distance between the current and the neighbor index. neighborDistance.SetVariable( Element.Part <V_DistanceBetween>( Nodes[(Element)neighborIndex.GetVariable()], Nodes[(Element)current.GetVariable()] ) + ((Element)distances.GetVariable())[(Element)current.GetVariable()] ) )); // Set the current neighbor's distance if the new distance is less than what it is now. IfBuilder ifBuilder = new IfBuilder(actionSet, (Element)neighborDistance.GetVariable() < WorkingDistance((Element)distances.GetVariable(), (Element)neighborIndex.GetVariable()) ); ifBuilder.Setup(); actionSet.AddAction(distances.SetVariable((Element)neighborDistance.GetVariable(), null, (Element)neighborIndex.GetVariable())); actionSet.AddAction(parentArray.SetVariable((Element)current.GetVariable() + 1, null, (Element)neighborIndex.GetVariable())); ifBuilder.Finish(); forBuilder.Finish(); actionSet.AddAction(ArrayBuilder <Element> .Build( // Add the current to the visited array. unvisited.SetVariable(Element.Part <V_RemoveFromArray>(unvisited.GetVariable(), current.GetVariable())), // Set the current node as the smallest unvisited. current.SetVariable(LowestUnvisited(Nodes, (Element)distances.GetVariable(), (Element)unvisited.GetVariable())) )); whileBuilder.Finish(); GetResult(); actionSet.AddAction(ArrayBuilder <Element> .Build( current.SetVariable(-1), distances.SetVariable(-1), connectedSegments.SetVariable(-1), neighborIndex.SetVariable(-1), neighborDistance.SetVariable(-1), parentArray.SetVariable(-1) )); Reset(); }
protected override void Generate(ITypeDescriptor typeDescriptor, CSharpSyntaxGeneratorSettings settings, CodeWriter writer, out string fileName, out string?path, out string ns) { ComplexTypeDescriptor descriptor = typeDescriptor as ComplexTypeDescriptor ?? throw new InvalidOperationException( "A result data factory can only be generated for complex types"); fileName = CreateResultFactoryName(descriptor.RuntimeType.Name); path = State; ns = CreateStateNamespace(descriptor.RuntimeType.NamespaceWithoutGlobal); ClassBuilder classBuilder = ClassBuilder .New() .SetName(fileName) .AddImplements( TypeNames.IOperationResultDataFactory.WithGeneric(descriptor.RuntimeType)); ConstructorBuilder constructorBuilder = classBuilder .AddConstructor() .SetTypeName(descriptor.Name); if (settings.IsStoreEnabled()) { AddConstructorAssignedField( TypeNames.IEntityStore, _entityStore, entityStore, classBuilder, constructorBuilder); } MethodCallBuilder returnStatement = MethodCallBuilder .New() .SetReturn() .SetNew() .SetMethodName(descriptor.RuntimeType.Name); foreach (PropertyDescriptor property in descriptor.Properties) { returnStatement .AddArgument(BuildMapMethodCall(settings, _info, property)); } IfBuilder ifHasCorrectType = IfBuilder .New() .SetCondition( $"{_dataInfo} is {CreateResultInfoName(descriptor.RuntimeType.Name)} {_info}") .AddCode(returnStatement); MethodBuilder createMethod = classBuilder .AddMethod("Create") .SetAccessModifier(AccessModifier.Public) .SetReturnType(descriptor.RuntimeType.Name) .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo)) .AddParameter( _snapshot, b => b.SetDefault("null") .SetType(TypeNames.IEntityStoreSnapshot.MakeNullable())); if (settings.IsStoreEnabled()) { createMethod .AddCode( IfBuilder.New() .SetCondition($"{_snapshot} is null") .AddCode( AssignmentBuilder .New() .SetLefthandSide(_snapshot) .SetRighthandSide($"{_entityStore}.CurrentSnapshot"))) .AddEmptyLine(); } createMethod.AddCode(ifHasCorrectType) .AddEmptyLine() .AddCode( ExceptionBuilder .New(TypeNames.ArgumentException) .AddArgument( $"\"{CreateResultInfoName(descriptor.RuntimeType.Name)} expected.\"")); var processed = new HashSet <string>(); AddRequiredMapMethods( settings, _info, descriptor, classBuilder, constructorBuilder, processed, true); classBuilder .AddProperty("ResultType") .SetType(TypeNames.Type) .AsLambda($"typeof({descriptor.RuntimeType.Namespace}.{descriptor.Implements[0]})") .SetInterface(TypeNames.IOperationResultDataFactory); classBuilder .AddMethod("Create") .SetInterface(TypeNames.IOperationResultDataFactory) .SetReturnType(TypeNames.Object) .AddParameter(_dataInfo, b => b.SetType(TypeNames.IOperationResultDataInfo)) .AddParameter( _snapshot, b => b.SetType(TypeNames.IEntityStoreSnapshot.MakeNullable())) .AddCode( MethodCallBuilder .New() .SetReturn() .SetMethodName("Create") .AddArgument(_dataInfo) .AddArgument(_snapshot)); classBuilder.Build(writer); }
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) { IfBuilder ifStatement = IfBuilder .New() .SetCondition( MethodCallBuilder .Inline() .SetMethodName(_entityId, "Name", nameof(string.Equals)) .AddArgument(concreteType.Name.AsStringToken()) .AddArgument(TypeNames.OrdinalStringComparison)); var entityTypeName = CreateEntityType( concreteType.Name, concreteType.RuntimeType.NamespaceWithoutGlobal); IfBuilder ifBuilder = BuildTryGetEntityIf(entityTypeName) .AddCode(CreateEntityConstructorCall(concreteType, false)) .AddElse(CreateEntityConstructorCall(concreteType, true)); ifStatement .AddCode(ifBuilder) .AddEmptyLine() .AddCode($"return {_entityId};"); methodBuilder .AddEmptyLine() .AddCode(ifStatement); } 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); }