public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { var alias = RoutingFrames.TypeOutputs[Variable.VariableType]; writer.WriteLine($"{alias} {Variable.Usage};"); writer.Write($"BLOCK:if (!{alias}.TryParse(segments[{Position}], out {Variable.Usage}))"); writer.WriteLine($"{RouteGraph.Context}.{nameof(HttpContext.Response)}.{nameof(HttpResponse.StatusCode)} = 400;"); writer.WriteLine(method.ToExitStatement()); writer.FinishBlock(); writer.BlankLine(); Next?.GenerateCode(method, writer); }
private static void writeConstructor(IGenerationModel generationModel, ISourceWriter writer) { var ctorArgs = generationModel.Fields.Select(x => x.CtorArgDeclaration).Join(", "); writer.Write($"BLOCK:public {generationModel.ClassName}({ctorArgs})"); foreach (var field in generationModel.Fields) { field.WriteAssignment(writer); } writer.FinishBlock(); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { var alias = RouteArgument.TypeOutputs[Variable.VariableType]; writer.WriteLine($"{alias} {Variable.Usage};"); writer.Write($"BLOCK:if (!{alias}.TryParse((string){Context.Usage}.Request.RouteValues[\"{Variable.Usage}\"], out {Variable.Usage}))"); writer.WriteLine( $"{RouteGraph.Context}.{nameof(HttpContext.Response)}.{nameof(HttpResponse.StatusCode)} = 400;"); writer.WriteLine(method.ToExitStatement()); writer.FinishBlock(); writer.BlankLine(); Next?.GenerateCode(method, writer); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { if (_inner.Any()) { writer.Write($"BLOCK:switch ({_event.Usage})"); foreach (var frame in _inner) { frame.GenerateCode(method, writer); } writer.FinishBlock(); } Next?.GenerateCode(method, writer); }
public static void Write(IGenerationModel generationModel, ISourceWriter writer) { writeClassDeclaration(generationModel, writer); writeFields(generationModel, writer); writer.BlankLine(); writeConstructor(generationModel, writer); writer.BlankLine(); writeHandleMethod(generationModel, writer); writer.FinishBlock(); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { writer.WriteComment("Check if the saga has been completed"); writer.Write($"BLOCK:if ({_handler.Usage}.{nameof(StatefulSagaOf<string>.IsCompleted)})"); writer.WriteComment("Delete the saga state entity"); writer.Write($"{_context.Usage}.{nameof(DbContext.Remove)}({_state.Usage});"); writer.FinishBlock(); // writer.Write("BLOCK:else"); // writer.WriteComment("Persist the saga state entity"); // writer.Write($"{_context.Usage}.{nameof(DbContext.Add)}({_state.Usage});"); // writer.FinishBlock(); writer.BlankLine(); Next?.GenerateCode(method, writer); }
// You have to override this method public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { var creation = $"var {Output.Usage} = new {Output.VariableType.FullNameInCode()}()"; if (Output.VariableType.CanBeCastTo <IDisposable>()) { // there is an ISourceWriter shortcut for this, but this makes // a better code demo;) writer.Write($"BLOCK:using ({creation})"); Next?.GenerateCode(method, writer); writer.FinishBlock(); } else { writer.WriteLine(creation + ";"); Next?.GenerateCode(method, writer); } }
public virtual void WriteSelectCode(ISourceWriter writer) { foreach (var route in ComplexArgRoutes) { writer.WriteComment("Look for odd shaped routes with complex parameter structures"); writer.Write($"if (Matches{route.VariableName}(segments)) return {route.VariableName};"); } if (_children.Any()) { writer.Write($"BLOCK:if (segments.Length > {LeafDepth})"); foreach (var node in _children) { writer.IfCurrentSegmentEquals(Depth, node.Segment, node.WriteSelectCode); } if (SpreadRoute != null) { writer.Return(SpreadRoute); } writer.ReturnNull(); writer.FinishBlock(); } foreach (var leaf in Leaves.OrderBy(x => x.LastSegment)) { writer.IfCurrentSegmentEquals(Depth, leaf.LastSegment, w => w.Return(leaf)); } if (TryFindLeafArgRoute(out var leafArg)) { writer.Return(leafArg); } if (SpreadRoute != null) { writer.Return(SpreadRoute); } writer.ReturnNull(); }
private void writeConstructorMethod(ISourceWriter writer, IList <InjectedField> args) { var ctorArgs = args.Select(x => x.CtorArgDeclaration).Join(", "); var declaration = $"BLOCK:public {TypeName}({ctorArgs})"; if (BaseConstructorArguments.Any()) { declaration = $"{declaration} : base({BaseConstructorArguments.Select(x => x.Usage).Join(", ")})"; } writer.Write(declaration); foreach (var field in args) { field.WriteAssignment(writer); } writer.FinishBlock(); }
public void Write(ISourceWriter writer) { writeDeclaration(writer); if (AllInjectedFields.Any()) { writeFieldDeclarations(writer, AllInjectedFields); writeConstructorMethod(writer, AllInjectedFields); } writeSetters(writer); foreach (var method in _methods.Where(x => x.WillGenerate())) { writer.BlankLine(); method.WriteMethod(writer); } writer.FinishBlock(); }
private void WriteConstructorMethod(ISourceWriter writer, HashSet <InjectedField> args) { var tempQualifier = args.Select(x => x.CtorArgDeclaration); var ctorArgs = string.Join(", ", tempQualifier); var declaration = $"public {this.TypeName}({ctorArgs})"; if (this.BaseConstructorArguments.Any()) { var tempQualifier1 = this.BaseConstructorArguments.Select(x => x.ArgumentName); declaration = $"{declaration} : base({string.Join(", ", tempQualifier1)})"; } writer.Block(declaration); foreach (var field in args) { field.WriteAssignment(writer); } writer.FinishBlock(); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { if (_createsSession) { writer.BlankLine(); writer.WriteComment("Open a new document session"); writer.Write( $"BLOCK:using (var {Session.Usage} = {_store.Usage}.{nameof(IDocumentStore.LightweightSession)}())"); } if (_context != null && _isUsingPersistence) { writer.Write( $"await {typeof(MessageContextExtensions).FullName}.{nameof(MessageContextExtensions.EnlistInTransaction)}({_context.Usage}, {Session.Usage});"); } foreach (var loaded in _loadedDocs) { loaded.Write(writer, Session); } Next?.GenerateCode(method, writer); foreach (var saved in _saved) { writer.Write($"{Session.Usage}.{nameof(IDocumentSession.Store)}({saved.Usage});"); } writer.BlankLine(); writer.WriteComment("Commit the unit of work"); writer.Write($"await {Session.Usage}.{nameof(IDocumentSession.SaveChangesAsync)}();"); if (_createsSession) { writer.FinishBlock(); } }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { if (InsideForEach) { writer.Write("BLOCK:foreach (var @event in events)"); } if (IsAsync) { writer.WriteLine($"{_aggregate.Usage} = await {ApplyMethodCollection.MethodName}(@event, {_aggregate.Usage}, {_session.Usage}, {_cancellation.Usage});"); } else { writer.WriteLine($"{_aggregate.Usage} = {ApplyMethodCollection.MethodName}(@event, {_aggregate.Usage}, {_session.Usage});"); } if (InsideForEach) { writer.FinishBlock(); } Next?.GenerateCode(method, writer); }
public void Write(ISourceWriter writer) { writeDeclaration(writer); var args = Args(); if (args.Any()) { writeFieldDeclarations(writer, args); writeConstructorMethod(writer, args); } writeSetters(writer); foreach (var method in _methods) { writer.BlankLine(); method.WriteMethod(writer); } writer.FinishBlock(); }
private static void writeHandleMethod(IGenerationModel generationModel, ISourceWriter writer) { var returnValue = generationModel.AsyncMode == AsyncMode.AsyncTask ? "async Task" : "Task"; if (generationModel.BaseType.IsInterfaceOrAbstract()) { returnValue = "override " + returnValue; } var variable = generationModel.InputVariable; writer.Write($"BLOCK:public {returnValue} Handle({variable.VariableType.FullName} {variable.Usage})"); generationModel.Top.GenerateCode(generationModel, writer); if (generationModel.AsyncMode == AsyncMode.ReturnCompletedTask) { writer.Write("return Task.CompletedTask;"); } writer.FinishBlock(); }
/// <summary> /// Writes the code for this method to the specified <see cref="ISourceWriter" />. /// </summary> /// <remarks> /// <para> /// This method will perform the necessary work to collect variables, both created in this method /// and by external <see cref="IVariableSource"/>s. /// </para> /// <para> /// This method does a lot of bookkeeping to keep track of <see cref="Frame"/>s and <see cref="Variable"/>s that /// are created and used by any added frames. The "top" <see cref="Frame"/> will have it's <see cref="Frame.Generate"/> /// method called twice, which in turn is expected to flow through all frames (using the assigned <see cref="Frame.NextFrame" /> /// property. /// </para> /// <para> /// The <see cref="Frame.Generate" /> method is called twice to allow the first run-through to create the required variables /// and to declare the dependencies. During this process we collect this information and, potentially, add in extra <see cref="Frame"/>s /// as required by the <see cref="IVariableSource"/>s that declare on-the-fly variables. The second time we will already have /// determined the variables and will actually write the code to the supplied <see cref="ISourceWriter" />. /// </para> /// </remarks> /// <param name="writer">The writer to output the code to.</param> public void WriteMethod(ISourceWriter writer) { // 1. Chain all existing frames together (setting their NextFrame property). var topFrame = ChainFrames(this.Frames); // 2. Clear out "all registered frames" to enable this method to be called multiple times. this._allRegisteredFrames.Clear(); // 3. The first time around is used for discovering the variables, ensuring frames // are fully created etc. No actual writing will occur var trackingWriter = new TrackingVariableWriter(this); topFrame.GenerateCode(trackingWriter, this, new MethodSourceWriter(trackingWriter, this, trackingWriter)); // 4. Determine the async mode of this method, which determines the result type and how // the actual return value is generated. Only do this is asyncMode is not set to // something else to allow overriding externally if (this.AsyncMode == AsyncMode.None) { this.AsyncMode = AsyncMode.AsyncTask; if (this._allRegisteredFrames.All(x => !x.IsAsync)) { this.AsyncMode = AsyncMode.None; } else { var lastFrame = this._allRegisteredFrames.Last(); if (this._allRegisteredFrames.Count(x => x.IsAsync) == 1 && lastFrame.IsAsync && lastFrame.CanReturnTask()) { this.AsyncMode = AsyncMode.ReturnFromLastNode; } } } // 5. Now find various types of variables to push to the GeneratedType, in addition to also // adding the creation frames to this method's collection if they do not already exist foreach (var variable in this._variables.Values.TopologicalSort(v => v.Dependencies)) { if (variable.Creator != null && !this._allRegisteredFrames.Contains(variable.Creator)) { // Find the first usage of this variable and place the frame before that. var firstUsage = this._allRegisteredFrames.FirstOrDefault(f => f.Uses.Contains(variable)); if (firstUsage == null) { this.Frames.Insert(0, variable.Creator); // throw new InvalidOperationException( // $"The variable '{variable}' has a creator Frame that has not been appended to this GeneratedMethod, " + // "nor does any Frame exist that Uses it, therefore we cannot determine where to place the creator Frame."); } else { this.Frames.Insert(this.Frames.IndexOf(firstUsage), variable.Creator); } this._allRegisteredFrames.Add(variable.Creator); } switch (variable) { case InjectedField field: this.GeneratedType.AllInjectedFields.Add(field); break; case Setter setter: this.GeneratedType.Setters.Add(setter); break; case StaticField staticField: this.GeneratedType.AllStaticFields.Add(staticField); break; } } // 6. Re-chain all existing frames as we may have pushed new ones topFrame = ChainFrames(this.Frames); // 7. We now have all frames & variables collected, lets do the final generation of code var returnValue = this.DetermineReturnExpression(); if (this.Overrides) { returnValue = "override " + returnValue; } var tempQualifier = this.Arguments.Select(x => x.Declaration); var arguments = string.Join(", ", tempQualifier); writer.Block($"public {returnValue} {this.MethodName}({arguments})"); // 7.1. Clear out "all registered frames" so we do not end up with large duplicated List this._allRegisteredFrames.Clear(); topFrame.GenerateCode(trackingWriter, this, new MethodSourceWriter(trackingWriter, this, writer)); this.WriteReturnStatement(writer); writer.FinishBlock(); }
public static void IfCurrentSegmentEquals(this ISourceWriter writer, int position, string routeSegment, Action <ISourceWriter> inner) { writer.Write($"BLOCK:if ({nameof(RouteSelector.Matches)}({RoutingFrames.Segments}[{position}], \"{routeSegment}\"))"); inner(writer); writer.FinishBlock(); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { writer.Write($"BLOCK:using (var {Session.Usage} = {_store.Usage}.{nameof(IDocumentStore.QuerySession)}())"); Next?.GenerateCode(method, writer); writer.FinishBlock(); }
/// <summary> /// Starts a finally block in code with the opening brace and indention for following lines. /// </summary> /// <param name="writer">Where to write to.</param> public static void Finally(this ISourceWriter writer) { writer.FinishBlock(); writer.Block("finally"); }
/// <summary> /// Writes "using ([declaration])" into the code and starts a new code /// block with a leading '{' character. /// </summary> /// <param name="writer">Where to write to.</param> /// <param name="declaration">The code that goes within the parenthesis of this using block (i.e. the expression that generates and optionally sets, the disposable object).</param> /// <param name="inner">The action that writes the body of the using block, passed the same writer to avoid closure allocation.</param> public static void Using(this ISourceWriter writer, string declaration, Action <ISourceWriter> inner) { writer.Block($"using ({declaration})"); inner(writer); writer.FinishBlock(); }
protected override void generateCode(GeneratedMethod method, ISourceWriter writer, Frame inner) { writer.Write($"BLOCK:if ({Condition})"); inner.GenerateCode(method, writer); writer.FinishBlock(); }
public override void GenerateCode(GeneratedMethod method, ISourceWriter writer) { writer.Write($"BLOCK:using ({_instance.ServiceType.FullNameInCode()} {Connection.Usage} = new {typeof(SqlConnection).FullName}({_settings.Usage}.{nameof(SqlServerSettings.ConnectionString)}))"); Next?.GenerateCode(method, writer); writer.FinishBlock(); }