예제 #1
0
        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);
        }
예제 #2
0
        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();
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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);
        }
예제 #7
0
        // 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);
            }
        }
예제 #8
0
        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();
        }
예제 #9
0
        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();
        }
예제 #10
0
        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();
        }
예제 #11
0
        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();
        }
예제 #12
0
        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();
            }
        }
예제 #13
0
        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);
        }
예제 #14
0
        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();
        }
예제 #15
0
        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();
        }
예제 #16
0
        /// <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();
        }
예제 #17
0
 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();
 }
예제 #18
0
 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();
 }
예제 #19
0
 /// <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");
 }
예제 #20
0
 /// <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();
 }
예제 #21
0
파일: IfBlock.cs 프로젝트: skovsende/jasper
 protected override void generateCode(GeneratedMethod method, ISourceWriter writer, Frame inner)
 {
     writer.Write($"BLOCK:if ({Condition})");
     inner.GenerateCode(method, writer);
     writer.FinishBlock();
 }
예제 #22
0
 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();
 }