diff --git a/docs/guide/compilation/assembly-generator.md b/docs/guide/compilation/assembly-generator.md index 89a8c019..db339f6d 100644 --- a/docs/guide/compilation/assembly-generator.md +++ b/docs/guide/compilation/assembly-generator.md @@ -11,22 +11,16 @@ the `LamarCompiler.AssemblyGenerator` class in the LamarCompiler library. Let's say that you have a simple interface in your system like this: - - ```cs public interface IOperation { int Calculate(int one, int two); } ``` -snippet source | anchor - Next, let's use `AssemblyGenerator` to compile code with a custom implementation of `IOperation` that we've generated in code: - - ```cs var generator = new AssemblyGenerator(); @@ -64,22 +58,18 @@ var operation = (IOperation)Activator.CreateInstance(type); // Use our new type var result = operation.Calculate(1, 2); ``` -snippet source | anchor - There's only a couple things going on in the code above: 1. I added an assembly reference for the .Net assembly that holds the `IOperation` interface -1. I passed a string to the `GenerateCode()` method, which successfully compiles my code and hands me back a .Net [Assembly](https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx) object -1. Load the newly generated type from the new Assembly -1. Use the new `IOperation` +2. I passed a string to the `GenerateCode()` method, which successfully compiles my code and hands me back a .Net [Assembly](https://msdn.microsoft.com/en-us/library/system.reflection.assembly(v=vs.110).aspx) object +3. Load the newly generated type from the new Assembly +4. Use the new `IOperation` If you're not perfectly keen on doing brute force string manipulation to generate your code, you can also use Lamar's built in [ISourceWriter](/guide/compilation/source-writer) to generate some of the code for you with all its code generation utilities: - - ```cs var generator = new AssemblyGenerator(); @@ -108,5 +98,3 @@ var operation = (IOperation)Activator.CreateInstance(type); var result = operation.Calculate(1, 2); ``` -snippet source | anchor - diff --git a/docs/guide/compilation/frames/extension-methods.md b/docs/guide/compilation/frames/extension-methods.md index 32a42071..47808626 100644 --- a/docs/guide/compilation/frames/extension-methods.md +++ b/docs/guide/compilation/frames/extension-methods.md @@ -9,8 +9,6 @@ determine how a type should be written *in code* with these extension methods in The functionality of `NameInCode()` is demonstrated below with some of its xUnit tests: - - ```cs [Theory] [InlineData(typeof(void), "void")] @@ -29,13 +27,9 @@ public void alias_name_of_task(Type type, string name) type.NameInCode().ShouldBe(name); } ``` -snippet source | anchor - Likewise, `FullNameInCode()` is shown below: - - ```cs [Theory] [InlineData(typeof(void), "void")] @@ -53,5 +47,3 @@ public void alias_full_name_of_task(Type type, string name) type.FullNameInCode().ShouldBe(name); } ``` -snippet source | anchor - diff --git a/docs/guide/compilation/frames/frame.md b/docs/guide/compilation/frames/frame.md index d39642f1..ecec0d04 100644 --- a/docs/guide/compilation/frames/frame.md +++ b/docs/guide/compilation/frames/frame.md @@ -13,8 +13,6 @@ To build a custom frame, you first need to create a new class that subclasses `F The one thing you absolutely have to do when you create a new `Frame` class is to override the `GenerateCode()` method. Take this example from Lamar itself for a frame that just injects a comment into the generated code: - - ```cs public class CommentFrame : SyncFrame { @@ -35,8 +33,6 @@ public class CommentFrame : SyncFrame } } ``` -snippet source | anchor - A couple things to note about the `GenerateCode()` method: diff --git a/docs/guide/compilation/frames/index.md b/docs/guide/compilation/frames/index.md index b351b1f2..fba86cee 100644 --- a/docs/guide/compilation/frames/index.md +++ b/docs/guide/compilation/frames/index.md @@ -19,21 +19,15 @@ The various types represent: Alright then, let's make this concrete. Let's say that we want to generate and use dynamic instances of this interface: - - ```cs public interface ISaySomething { void Speak(); } ``` -snippet source | anchor - Moreover, I want a version of `ISaySomething` that will call the following method and write the current time to the console: - - ```cs public static class NowSpeaker { @@ -43,15 +37,11 @@ public static class NowSpeaker } } ``` -snippet source | anchor - Our dynamic class for ISaySomething will need to pass the current time to the now parameter of that method. To help out here, there's some built in helpers in Lamar specifically to write in the right code to get the current time to a variable of DateTime or DateTimeOffset that is named "now." To skip ahead a little bit, let's generate a new class and object with the following code: - - ```cs // Configures the code generation rules // and policies @@ -79,8 +69,6 @@ method.Frames.Add(@call); // Compile the new code! assembly.CompileAll(); ``` -snippet source | anchor - After all that, if we interrogate the source code for the generated type above (type.SourceCode), we'd see this ugly generated code: @@ -106,8 +94,6 @@ Some notes about the generated code: So now let's look at how Lamar was able to add the code to pass along DateTime.UtcNow. First off, let's look at the code that just writes out the date variable: - - ```cs public class NowFetchFrame : SyncFrame { @@ -127,22 +113,18 @@ public class NowFetchFrame : SyncFrame } } ``` -snippet source | anchor - In the frame above, you'll see that the `GenerateCode()` method writes its code into the source, then immediately turns around and tells the next Frame - if there is one - to generated its code. As the last step to write out the new source code, Lamar: 1. Goes through an effort to find any missing frames and variables -1. Sorts them with a topological sort (what frames depend on what other frames or variables, what variables are used or created by what frames) -1. Organizes the frames into a single linked list -1. Calls `GenerateCode()` on the first frame +2. Sorts them with a topological sort (what frames depend on what other frames or variables, what variables are used or created by what frames) +3. Organizes the frames into a single linked list +4. Calls `GenerateCode()` on the first frame In the generated method up above, the call to `NowSpeaker.Speak(now)` depends on the now variable which is in turn created by the `NowFetchFrame`, and that's enough information for Lamar to order things and generate the final code. Lastly, we had to use a custom `IVariableSource` to teach Lamar how to resolve the now variable. That code looks like this: - - ```cs public class NowTimeVariableSource : IVariableSource { @@ -167,8 +149,6 @@ public class NowTimeVariableSource : IVariableSource } } ``` -snippet source | anchor - Out of the box, the Lamar + [Jasper](https://jasperfx.github.io) combination uses variable sources for: diff --git a/docs/guide/compilation/frames/injected-fields.md b/docs/guide/compilation/frames/injected-fields.md index 043c8db0..3ed6108c 100644 --- a/docs/guide/compilation/frames/injected-fields.md +++ b/docs/guide/compilation/frames/injected-fields.md @@ -11,8 +11,6 @@ As an example, let's take the `WhatTimeIsIt` generated type from the [frames mod this time generate the class with the assumption that the "now" time is injected into the generated type's constructor like this: - - ```cs var assembly = GeneratedAssembly.Empty(); var type = assembly.AddType("WhatTimeIsIt", typeof(ISaySomething)); @@ -30,8 +28,6 @@ method.Frames.Add(@call); assembly.CompileAll(); ``` -snippet source | anchor - At runtime as Lamar tries to write the code for a new generated type, it will seek out any or all `InjectedField` variables used within any of the methods and use those to generate a constructor function. The generated code for the dynamic type diff --git a/docs/guide/compilation/frames/variables.md b/docs/guide/compilation/frames/variables.md index af15e142..f4cbea43 100644 --- a/docs/guide/compilation/frames/variables.md +++ b/docs/guide/compilation/frames/variables.md @@ -4,8 +4,6 @@ The `Variable` class in LamarCodeGeneration models the CLR type and usage of a v Here are some samples of creating variable objects with a variable type and name: - - ```cs // Create a connection for the type SqlConnection // with the name "conn" @@ -19,21 +17,15 @@ var conn2 = new Variable(typeof(SqlConnection), "conn2"); var conn3 = Variable.For(); conn3.Usage.ShouldBe("sqlConnection"); ``` -snippet source | anchor - ## Default Naming If you do not give a name for a variable, Lamar will derive a default variable name from the type like this: - - ```cs var widget = Variable.For(); widget.Usage.ShouldBe("widget"); ``` -snippet source | anchor - The best way to understand the full rules for deriving the default variable names is to just peek at the [unit tests within the Lamar codebase](https://github.com/JasperFx/lamar/blob/master/src/Lamar.Testing/Codegen/VariableTests.cs). @@ -43,8 +35,6 @@ The best way to understand the full rules for deriving the default variable name If a variable is created by a [Frame](/guide/compilation/frames/frame), you really want to mark that relationship by either passing the creating frame into the constructor function like this: - - ```cs public class NowFetchFrame : SyncFrame { @@ -64,46 +54,30 @@ public class NowFetchFrame : SyncFrame } } ``` -snippet source | anchor - ## Overriding Variable Usage or Type Do this sparingly, but you can override the name or usage and type of a previously built variable like this: - - ```cs var service = new Variable(typeof(IService), "service"); service.OverrideName("myService"); service.OverrideType(typeof(WhateverService)); ``` -snippet source | anchor - - ## Derived Variables Variables don't have to mean literal C# variables in the generated code. They can be derived values like this example: - - ```cs var now = new Variable(typeof(DateTime), $"{typeof(DateTime).FullName}.{nameof(DateTime.Now)}"); ``` -snippet source | anchor - - ## Dependencies to Other Variables For the sake of frame ordering, you might need to give Lamar a hint that your variable depends on another variable. Here's an example of doing that with the `HttpResponse` type from ASP.Net Core: - - ```cs var context = Variable.For(); var response = new Variable(typeof(HttpResponse), $"{context.Usage}.{nameof(HttpContext.Response)}"); response.Dependencies.Add(context); ``` -snippet source | anchor -