Skip to content

Commit

Permalink
[.NET] [sourcegen] Add readmes
Browse files Browse the repository at this point in the history
  • Loading branch information
burkenyo authored and speth committed Aug 17, 2022
1 parent a1646f7 commit 21c0135
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
31 changes: 31 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -101,3 +101,34 @@
* Code in `.py` and `.pyx` files needs to be written to work with Python 3
* The minimum Python version that Cantera supports is Python 3.6, so code should only use features added in Python 3.6 or earlier
* Please use double quotes in all new Python code

## C#

* C# coding conventions should follow https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions
* All identifiers should follow the naming conventions in the above document including
* Prefixing with `_` for private instance fields (`_foo`, unlike C++)
* Prefixing with `s_` for private static fields (`s_bar`) and `t_` for private
thread-local fields (`t_baz`).
* Intial caps names for class methods (`DoSomething()`, unlike C++)
* Give the opening brace of a statement block its own line (unlike C++), except empty
blocks, which may be written as an `{ }` (for example, a constructor which calls
a base-class constructor only).
* Use only one statement per line
* Always use statement blocks (`{ ... }`) for the bodies of statements that can take
either a statement block or a single statement (`if`, `for`, etc.)
* Use file-scoped namespaces in each new file.
* Do not take any extra Nuget dependencies in the `Cantera.csproj` project.
* Use C# XML Doc-Comments on public members, including at least the `<summary>` tag.
* Do not expose any code requiring the `unsafe` keyword via a public API
(pointers, the `fixed` statement, etc). Pointers are used for the high-preformance
interop layer with the native Cantera library, but such access should have a
“safe” wrapper, such as a `Span<T>` or a managed array.
* Do not allow exceptions to pass uncaught out of a callback invoked from native code,
as the interop layer cannot marshall exceptions between managed and native code,
and the process will crash. Use `CallbackException.Register()` within a catch-all
block to log the exception for later throwing back in managed code.
* The primary API for accessing Cantera is the `Application` class, which handles
required static initialization of the library. When exposing a new wrapper for CLib
functionality, do not expose a public constructor. Rather, mark the constructor
`internal` and wrap it in an appopriate factory method in the `Application` class
(`public static CreateFoo(string filename) { ... }`).
39 changes: 39 additions & 0 deletions interfaces/dotnet/README.md
@@ -0,0 +1,39 @@
# Cantera – .NET Interface

This directory and its children contain the interface to Cantera for .NET languages
such as C# and F#. It is written in C# and supports .NET Standard 2.0
(for the primary project) and .NET 6 (and newer) on all platforms that support both
.NET and the Cantera C++ library.

### Project Layout

The primary C# project is Cantera.csproj. This project uses P/Invoke extensively with
the native Cantera library via the Cantera C interface (CLib), and wraps the low-level
interfaces with classes and concepts familiar to a .NET developer. As part of the build
process, it invokes [sourcegen](/interfaces/sourcegen)
to scaffold the interop code and some of the code for the wrapper objects, such as
simple properties which can mapped directly to CLib getter and setter functions.
Cantera.csproj targets .NET Standard 2.0 and .NET 6. This project will be released as
a NuGet package.

Cantera.Tests.csproj contains the unit tests for the Cantera .NET library and targets
.Net 6.

The examples directory contains seperate projects for each Cantera example. These will
be packaged as a template for use with the .NET CLI, allowing developers to create a
solution with all the examples using `dotnet new`.

### Contributing

Like all of Cantera, we welcome cotributions to the .NET interface. Contributors should
read the code of coduct and check out our general and C#-specific coding standards in
[CONTRIBUTING.md](/CONTRIBUTING.md). Please note that contributing to the .NET interface
requires a relatively advanced understanding of C#. This includes comfortability with
`unsafe` blocks and interop concepts such as raw pointers, understanding of how to use
`Span<T>` and similar memory APIs, and a solid grip on object-oriented library design.

### Status

The .NET Interface is in preview and still missing many features
needed for parity with the C++ and Python interfaces. Interested contributors can see
the status of the project at [Enhacement #156](https://github.com/Cantera/enhancements/issues/156).
31 changes: 31 additions & 0 deletions interfaces/sourcegen/README.md
@@ -0,0 +1,31 @@
## sourcegen – Python based source generator for creating Cantera interfaces for other languages

A common script “parses” the CLib header files and generates intermediate objects which represent the functions:
* return type (string)
* name (string)
* params: list of
* return type
* name

The script delegates the source generation to a language-specific module. The module creates the source files in a location appropriate to the build for that languages build process.

The common script takes two mandatory arguments:
1. The name of the language-specific module.
1. The full path of the directory where generated files shall be placed.

The language-specific modules export a class named “SourceGenerator”:
1. A constructor which takes the output directory and the parsed config object\
The constructor stores these for later use.
1. A “generate_source” function which will takes the included file and its list of parsed functions\
The generate_source function generates source files for each file it receives as it is called
and/or builds up data structures containing source symbols to be generated later.
1. A “finalize” function which takes no arguments
The finalize function performs any final code generation tasks and necessary clean up.

The implementation details for the SourceGenerator classes is of course highly dependent on the build process of the destination language.

In addition, each module can contain a yaml-based config file named “config.yaml”. The core script recoginizes a key called “ignore”, which is a map. Each key in the “ignore” map is the name of a clib header file. The value is an array which is either empty or contains strings representing function names defined in the header file. The core script interprets the ignore map as follows:
* for each key followed by an empty array, the entire file is excluded from code generation
* for each key followed-by a non-empty array, only the functions referenced in the array are excluded from code generation.

The config file may contain additional values for use by the language-specific module.

0 comments on commit 21c0135

Please sign in to comment.