You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mostly just better documentation and tweaks. Snuck in a minor point release update for nuget dependencies.
- Add more documentation around assembly, csproj, sln, nuget references
- More detail on theming.
- The new `args` feature for csx
- Add contributing section and architecture.md documents
This document describes the design of csharprepl at a high level. It's useful if you want to contribute to csharprepl and are trying to understand how the code is organized and what the various responsibilities are.
4
+
5
+
Broadly, there are three main components to csharprepl's architecture:
6
+
7
+
1.[Roslyn libraries](https://github.com/dotnet/roslyn) - Written by Microsoft, these provide both high-level and low-level APIs for building, running, and analyzing C# code.
8
+
1.[PrettyPrompt library](https://github.com/waf/PrettyPrompt) - the PrettyPrompt library was written alongside csharprepl, and is packaged as a separate nuget package and repository. It's a Console.ReadLine replacement, and handles terminal features like accepting input, drawing autocompletion menus, syntax highlighting, keybindings, etc, and generally handles the "user experience" of the prompt. It's a general library, and does not know anything about C#; it instead provides callbacks that csharprepl implements to add C#-specific behavior.
9
+
1. csharprepl (this repository) - This application uses PrettyPrompt to collect input from the user, invokes the Roslyn APIs on that input, and then prints the result.
10
+
11
+
Each of the above parts is described in more detail below.
12
+
13
+
## Roslyn libraries
14
+
15
+
csharprepl uses two main areas of the Roslyn libraries:
16
+
17
+
- C# Scripting API ([docs](https://github.com/dotnet/roslyn/blob/b796152aff3a7f872bd70db26cc9f568bbdb14cc/docs/wiki/Scripting-API-Samples.md))
18
+
- C# Workspaces API ([docs](https://docs.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/work-with-workspace))
19
+
20
+
The C# Scripting API allows for evaluating strings containing C# and returns the result. This is the core of the REPL experience; this core is quite simple, and a basic REPL could be implemented in a couple of lines of C# using this API. In csharprepl, this is in `ScriptRunner.cs`.
21
+
22
+
The C# Workspaces API provides all the ancillary editor features in csharprepl, like syntax highlighting, autocompletion, documentation tooltip information, etc. A workspace is conceptually similar to a Visual Studio solution, and it has multiple projects all contained in memory. Each line of a REPL is implemented as a single project with a single document, and each project has a reference to the previously submitted project. In other words, the workspace is a linked-list of projects, where each project is a line of the REPL. Submitting a new line in csharprepl will create a new project and document. Features like syntax highlighting and autocompletion read this document as their input.
23
+
24
+
These two APIs are quite separate; one of the main tasks of csharprepl is to ensure that when code is evaluated in the REPL, both of these APIs receive consistent information (see `RoslynServices.cs`).
25
+
26
+
## PrettyPrompt library
27
+
28
+
This prompt library is initialized/called in the main `Program.cs`, in the "Read" part of the "Read-Eval-Print-Loop." It's instantiated with callback functions to handle syntax highlighting, autocompletion, and more; these callbacks invoke the above `RoslynServices.cs` class to fulfill the callbacks. The `PromptAdapter` class maps between Roslyn concepts (e.g. a span of text with the syntax classification) and the PrettyPrompt concepts (e.g. a span of text with a syntax highlight color).
29
+
30
+
## csharprepl
31
+
32
+
As previously described, csharprepl serves as an intermediary between the above two libraries. There are four main tasks that csharprepl performs:
33
+
34
+
-`Program.cs` handles basic features like command line arguments, help documentation, and the core read-eval-print-loop.
35
+
- Initialization logic is managed in `RoslynServices.cs`. The Roslyn libraries do a lot of heavy lifting and are relatively slow to initialize; RoslynServices serves as an entry point to all Roslyn services, and it manages this initialization in the background to keep csharprepl snappy. It ensures that when the Roslyn services are called, they either don't block, or they wait for initialization to complete if required.
36
+
- You can see this in action by starting csharprepl and typing some C# code really quickly before initialization can fully complete. You'll be able to type without delay as it won't block, but you might see syntax highlighting kick in a few seconds later, after initialization is complete; this is what RoslynServices is managing.
37
+
- Synchronization between the C# Scripting API and C# Workspaces API, as described in *Roslyn libraries* above, is also managed by `RoslynServices.cs`. Upon successful evaluation of a script, it updates the workspaces API with a new project and updates the active document to use for syntax highlighting, autocompletion, and more.
38
+
- Assembly reference management - Management of [Shared Frameworks](https://natemcmaster.com/blog/2017/12/21/netcore-primitives/), [implementation vs reference assemblies](https://docs.microsoft.com/en-us/dotnet/standard/assembly/reference-assemblies), and adding references dynamically are handled in the `AssemblyReferenceService.cs`. This class is called by our MetadataReferenceResolver implementation, which is an extension point provided by Roslyn.
39
+
- This MetadataReferenceResolver is responsible for evaluating `#r` statements, and delegates for assembly references, nuget package installation, csproj/sln references, and shared framework loading. The implementation is in `CompositeMetadataReferenceResolver.cs`
Copy file name to clipboardExpand all lines: README.md
+20-8
Original file line number
Diff line number
Diff line change
@@ -104,6 +104,7 @@ the [MSDN documentation for `AddDays`](https://docs.microsoft.com/en-US/dotnet/a
104
104
Use the `#r` command to add assembly or nuget references.
105
105
106
106
- For assembly references, run `#r "AssemblyName"` or `#r "path/to/assembly.dll"`
107
+
- For project references, run `#r "path/to/project.csproj"`. Solution files (.sln) can also be referenced.
107
108
- For nuget references, run `#r "nuget: PackageName"` to install the latest version of a package, or `#r "nuget: PackageName, 13.0.5"` to install a specific version (13.0.5 in this case).
-`-r <dll>` or `--reference <dll>`: Add an assembly reference. Can be specified multiple times.
131
+
-`-r <dll>` or `--reference <dll>`: Reference an assembly, project file, or nuget package. Can be specified multiple times. Uses the same syntax as `#r` statements inside the REPL. For example, `csharprepl -r "nuget:Newtonsoft.Json" "path/to/myproj.csproj"`
132
+
- When an assembly or project is referenced, assemblies in the containing directory will be added to the assembly search path. This means that you don't need to manually add references to all of your assembly's dependencies (e.g. other references and nuget packages). Referencing the main entry assembly is enough.
131
133
-`-u <namespace>` or `--using <namespace>`: Add a using statement. Can be specified multiple times.
132
-
-`-f <framework>` or `--framework <framework>`: Reference a [shared framework](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage-app). Available shared frameworks depends on the local .NET installation, and can be useful when running a ASP.NET application from the REPL. Example frameworks are:
134
+
-`-f <framework>` or `--framework <framework>`: Reference a [shared framework](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/metapackage-app). The available shared frameworks depends on the local .NET installation, and can be useful when running an ASP.NET application from the REPL. Example frameworks are:
133
135
- Microsoft.NETCore.App (default)
134
136
- Microsoft.AspNetCore.All
135
137
- Microsoft.AspNetCore.App
136
138
- Microsoft.WindowsDesktop.App
137
-
-`-t <theme.json>` or `--theme <theme.json>`: Read a theme file for syntax highlighting. The [NO_COLOR](https://no-color.org/) standard is supported.
139
+
-`-t <theme.json>` or `--theme <theme.json>`: Read a theme file for syntax highlighting. This theme file associates C# syntax classifications with colors. The color values can be full RGB, or ANSI color names (defined in your terminal's theme). The [NO_COLOR](https://no-color.org/) standard is supported.
138
140
-`-v` or `--version`: Show version number and exit.
139
-
-`-h` or `--help`: Show this help and exit.
141
+
-`-h` or `--help`: Show help and exit.
140
142
-`response-file.rsp`: A filepath of an .rsp file, containing any of the above command line options.
141
-
-`script-file.csx`: A filepath of a .csx file, containing lines of C# to evaluate before starting the REPL.
143
+
-`script-file.csx`: A filepath of a .csx file, containing lines of C# to evaluate before starting the REPL. Arguments to this script can be passed as `<additional-arguments>`, after a double hyphen (`--`), and will be available in a global `args` variable.
142
144
143
145
## Integrating with other software
144
146
@@ -174,6 +176,16 @@ This project is far from being the first REPL for C#. Here are some other projec
174
176
175
177
**csi.exe** ships with C# and is a command line REPL. It's great because it's a cross platform REPL that comes out of the box, but it doesn't support syntax highlighting or autocompletion.
176
178
177
-
**dotnet script** allows you to run C# scripts from the .NET CLI. It has a REPL built-in, but the predominant focus seems to be as a script runner. It's a good alternative though, and has a strong community following.
179
+
**dotnet script** allows you to run C# scripts from the command line. It has a REPL built-in, but the predominant focus seems to be as a script runner. It's a great tool, though, and has a strong community following.
178
180
179
-
**dotnet interactive** is a tool from Microsoft that creates a Jupyter notebook for C#, runnable through Visual Studio Code.
181
+
**dotnet interactive** is a tool from Microsoft that creates a Jupyter notebook for C#, runnable through Visual Studio Code. It also provides a general framework useful for running REPLs.
182
+
183
+
## Contributing
184
+
185
+
If you'd like to help out, thanks! We use Visual Studio 2022 for development, though any standard .NET 5 development environment should work. Please read through these guidelines to get started:
186
+
187
+
- Read through the [ARCHITECTURE.md](/ARCHITECTURE.md) file to understand how csharprepl works. Depending on what you want to do, changes to the underlying PrettyPrompt library may be required.
188
+
- For new features, please open an issue first to discuss and design the feature. This will help reduce the chance of conflicting designs.
189
+
- Please include an xunit test, and ensure any code warnings are resolved.
0 commit comments