-
-
Notifications
You must be signed in to change notification settings - Fork 400
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
51 changed files
with
7,717 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# SilkManager | ||
## Information | ||
- Introduced in Preview 2 | ||
- Active in 1.1.1 | ||
- Deprecated in 1.2 | ||
- Removed in 2.0 | ||
|
||
## Summary | ||
SilkManager was our solution to accessing classes and interfaces that needed to be shared across packages without introducing a | ||
direct (often circular) dependency. | ||
|
||
## Why are we removing it? | ||
In Silk.NET 2.0, we intend to couple all of the default windowing implementations into one package to eliminate the storage | ||
overhead of having a bridge DLL with just one class in it (Silk.NET.Windowing and Silk.NET.Input). This is because .NET 5 | ||
makes cross-platform a lot easier. The new package structure will look like this: | ||
|
||
- Silk.NET.Windowing | ||
- Silk.NET.Windowing.Desktop merged into this package | ||
- depends on Silk.NET.Windowing.Common | ||
- Silk.NET.Input | ||
- Silk.NET.Input.Desktop merged into this package | ||
- depends on Silk.NET.Input.Common | ||
- depends on Silk.NET.Windowing.Common (subject to change) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Vulkan-Specific Views and Windows (i.e. IVulkanView, IVulkanWindow) | ||
## Information | ||
- Introduced in Preview 3 | ||
- Active in 1.1.1 | ||
- Deprecated in 1.2 | ||
- Removed in 2.0 | ||
|
||
## Why are we removing it? | ||
Currently, Vulkan-specific functions are accessed by first checking if a IView or IWindow supports Vulkan, and then | ||
casting the IView or IWindow to a IVulkanView or IVulkanWindow respectively. This can get quite messy. As such, we | ||
decided to instead move all API or platform specific functions into interfaces accessed via a nullable property in | ||
IView and IWindow, as follows: | ||
|
||
### Old | ||
```cs | ||
if (window.IsVulkanSupported && window is IVulkanWindow vkWindow) | ||
{ | ||
vkWindow.CreateSurface(...); | ||
} | ||
``` | ||
|
||
### New | ||
|
||
```cs | ||
if (window.VkSurface != null) | ||
{ | ||
window.VkSurface.CreateSurface(...); | ||
} | ||
``` | ||
|
||
All OpenGL functions will get the same treatment, but both the Vulkan-specific and OpenGL-specific functions will | ||
continue to be accessible through the main IView and IWindow interfaces through extension methods. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# SilkTouch | ||
|
||
SilkTouch is the Silk.NET project's C# native interoperability code generation stack. It contains useful generators which together generate the majority of the library's codebase. | ||
|
||
It does this by centering all parts around a [common symbol layer](./symbol-layer/README.md), which allows other parts to be used in any configuration deemed useful, parts don't have a way other then the symbol layer to exchange data, enforcing interoperability. | ||
|
||
Learn more about each individual cornerstone of the SilkTouch Stack: | ||
|
||
- [Symbol Layer](./symbol-layer/README.md) | ||
- [Emitter](emitter.md) | ||
- [Scraper](scraper.md) | ||
|
||
TODO: Add a link to the original proposal once the proposals folder has been reorganised according to the Software Development Plan. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Emitter | ||
|
||
The emitter is responsible for creating Roslyn C# Code Symbols from our symbol layer. | ||
|
||
See [here](./about%20formatting.md) for how formatting works, and [here](./visitor.md) for details on the visitor implementation. | ||
|
||
In general the emitter tries it's best to be very basic doing only the job of 1:1 translating shared symbol layer into C# roslyn symbols. |
38 changes: 38 additions & 0 deletions
38
docs/for-contributors/generators/emitter/about formatting.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
# About Formatting | ||
|
||
This document is just a sink for all things related formatting. | ||
If your code is acting up and spitting out unreadable garbage, or you want to improve code style - READ THIS FRIST! | ||
|
||
## Indentation | ||
|
||
The emitter implements a very basic system based on 4 members: `Indent()`, `Outdent()`, `NewLine`, `Indentation` | ||
|
||
- `Indent()`: After this call indentation will be more | ||
- `Outdent()`: After this call indentation will be less | ||
- `NewLine`: Put this when you want to go to the next line. It automatically handles putting the right amount of spaces after. | ||
- `Indentation`: only use this if absolutely necessary. It's only there as a safety net | ||
|
||
The common pattern is something like this: | ||
|
||
```cs | ||
Indent() | ||
var members = memberSymbols.Select(s => { | ||
VisitSomething(s); | ||
if (_syntax is not SomeSyntax memberSyntax) | ||
throw Something; | ||
ClearState(); | ||
memberSyntax = memberSyntax.WithLeadingTrivia(NewLine); | ||
return memberSyntax; | ||
}).ToArray(); | ||
Outdent(); | ||
|
||
// use members somehow | ||
``` | ||
|
||
Note the `.ToArray()` this forces execution to happen during the indent/outdent scope. | ||
|
||
## On Trivia | ||
|
||
Prefer using leading trivia over trailing trivia. This is because leading trivia is impossible to leak outside of the symbol you are working on, while trailing trivia easily does this. While sometimes inconvinient because the parent symbol you have no control over leaks it's trivia into your symbol, it's still preferable - had the parent symbol followed this advice it couldn't leak into your symbol right now. Do us all a favor. | ||
|
||
Similar things apply at the micro level too - use leading trivia on braces over trailing trivia on identifiers. This improves the editing experience when adding extra things later and massively improves the reviewers understanding, as there are simply fewer changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# Visitor | ||
|
||
See [here](../symbol-layer/symbol-visitor.md) for details on how the base symbol visitor works. | ||
|
||
To Transform our internal symbol layer to C# code a visitor (`CSharpEmitter.Visitor`) is used. | ||
|
||
## State | ||
|
||
To communicate produced syntax nodes with the levels above the current one the state variables are used. | ||
Therefore its important to enshure that this state is clear at all times. (Using `AssertClearState` & `ClearState`) | ||
|
||
## Depth First | ||
|
||
In general we try to push symbols down as far as possible to avoid code duplication and increase testable surface area. | ||
The best example of this that instead of creating identifier tokens / identifier name syntax nodes inline (which would be very easy) we visit the identifier, letting the `VisitIdentifier` function create those, and then take what we need, using a pattern like | ||
|
||
```cs | ||
VisitIdentifier(structSymbol.Identifier); | ||
if (_syntaxToken is not { } identifierToken) | ||
throw new InvalidOperationException("Some Identifier was not visited correctly"); | ||
ClearState(); | ||
``` | ||
|
||
when a token is required, or | ||
|
||
```cs | ||
VisitIdentifier(fieldSymbol.Type.Identifier); | ||
if (_syntax is not IdentifierNameSyntax typeIdentifierSyntax) | ||
throw new InvalidOperationException("Some Identifier was not visited correctly"); | ||
ClearState(); | ||
``` | ||
|
||
when a syntax node is required. | ||
|
||
## Trivia | ||
|
||
The visitor is intended to produce "valid" code, that means it can be formatted using .ToFullString and the resulting code is valid and can be parsed back by roslyn. | ||
In addition we try to avoid elastic trivia wherever possible. For performance reasons we don't want to normalize our trivia / syntax internally, but elastic trivia would be thrown away when doing so, therefore we try to avoid generating elastic trivia in the first place. | ||
Integration tests should test for elastic trivia, although their primary purpose is to check the resulting formatted string. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Scraper | ||
|
||
The Scraper will call into ClangSharp to generate XML from the given C headers (`GenerateXML`), and then convert the output produced by ClangSharp into symbols defined by the [Symbol Layer](./symbol-layer/README.md) (`ScrapeXML`). | ||
|
||
The Scraper should stay quite small and easy to use, as it is also the window to all the complexity that comes from C++, Clang, header, etc. It should only bridge the XML output into the symbol layer. | ||
|
||
## Scraping XML | ||
|
||
To scrape XML there is a visitor that visits each XML node and outputs several symbols per node. | ||
This is what happens in `XmlVisitor.cs`, called from `ScrapeXML`. | ||
|
||
## Generating XML using ClangSharp | ||
|
||
This is what happens in `ClangScraper.cs`, which is configured using `ClangScraperConfiguration.cs`. | ||
The XML is generated by the `ClangSharp.PInvokeGenerator` see [dotnet/ClangSharp](https://github.com/dotnet/ClangSharp) and the [PInvokeGenerator file](https://github.com/dotnet/ClangSharp/blob/main/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs). | ||
Check XML docs for details on what methods do. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Symbol Layer | ||
|
||
The symbol layer is a set of types in the Silk.NET.SilkTouch.Symbols, all inheriting from the central Silk.NET.SilkTouch.Symbols.Symbol type. | ||
|
||
The symbol layer is intended as a way to represent data passed between components of SilkTouch and is entirely immutable, with the only exception being the [Type Store](./type-store.md). | ||
|
||
The way to update & iterate symbols is using a [Symbol Visitor](./symbol-visitor.md). | ||
|
||
See [symbols](./symbols/README.md) for a list of all symbols, their visitor method, test details, etc. | ||
|
||
See [type references](./type-references.md) for an explanation of type references. |
19 changes: 19 additions & 0 deletions
19
docs/for-contributors/generators/symbol-layer/symbol-visitor.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Symbol Visitor | ||
|
||
A symbol visitor visits each symbol and then calls the appropriate methods to recursively visit all parts. | ||
Each symbol visitor has access to a [type store](./type-store.md). It has to be provided in the constructor of every symbol visitor. | ||
It's generally adviced to simply bubble up this constructor parameter to users of your type. | ||
|
||
## Updating Symbols | ||
|
||
Each method returns the same type it gets as parameter, so prefer to override the most specific method possible. | ||
For example, if you wish to rename all `TypeSymbol`s, override `VisitTypeSymbol`. But if you want to add a field to every struct, override `VisitStructSymbol`. If you want to rewrite the type of a symbol, for example generate a class for every struct, again, override the most specific method that is compatible with both (in this case `VisitTypeSymbol`) and do type checks as necessary. | ||
|
||
### Type IDs | ||
|
||
See [type store](./type-store.md) for details on what type Ids are. | ||
**Do not change type IDs when visiting symbols. This breaks all references to that type.** | ||
|
||
## Managing State | ||
|
||
While the base `SymbolVisitor` is stateless, derived types are free to introduce (mutable) state. This allow propagating state other then the new symbol up the tree. |
55 changes: 55 additions & 0 deletions
55
docs/for-contributors/generators/symbol-layer/symbols/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Symbols | ||
|
||
This document / folder is for tracking all the available symbols, and documenting what creation of one entails. | ||
|
||
## Relation to SymbolVisitor | ||
|
||
In general each symbol listed below should have a corresponding method `VisitMySymbol` the only exception being `UnresolvedTypeReference` as only few visitors should ever interact with it. | ||
|
||
## List | ||
|
||
(Order alphabetically please!) | ||
|
||
Parent Symbols (Unlisted, abstract): | ||
| Name | See Also | | ||
| ---- | -------- | | ||
| MemberSymbol | | | ||
| Symbol | | | ||
| TypeReference | [here](../type-references.md) | | ||
| TypeSymbol | | | ||
| MethodSymbol | | ||
|
||
| Name | Symbol Layer File | Symbol Layer Tests | Emitter Tests | | ||
| ---------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | | ||
| ClassSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ClassSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ClassSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ClassSymbolTests.cs) | | ||
| ExternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/ExternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/ExternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/ExternalTypeReferenceTests.cs) | | ||
| FunctionPointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FunctionPointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FunctionPointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/FunctionPointerTypeReferenceTests.cs) | | ||
| FieldSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/FieldSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/FieldTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterFieldTests.cs) | | ||
| IdentifierSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/IdentifierSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/IdentifierTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/IdentifierSymbolTests.cs) | | ||
| InternalTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/InternalTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/InternalTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/InternalTypeReferenceTests.cs) | | ||
| NamespaceSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/NamespaceSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/NamespaceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterNamespaceTests.cs) | | ||
| PointerTypeReference | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/PointerTypeReference.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/PointerTypeReferenceTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/PointerTypeReferenceTests.cs) | | ||
| StaticExternalMethodSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StaticExternalMethodSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StaticExternalMethodSymbolTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/StaticExternalMethodSymbolTests.cs) | | ||
| StructSymbol | [here](../../../../../src/generators/Silk.NET.SilkTouch.Symbols/StructSymbol.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/StructTests.cs) | [here](../../../../../tests/Silk.NET.SilkTouch.Emitter.Tests/EmitterStructTests.cs) | | ||
| UnresolvedTypeReference | [here](src/generators/Silk.NET.SilkTouch.Symbols/UnresolvedTypeReference.cs) | [here](tests/Silk.NET.SilkTouch.Symbols.Tests/SymbolVisitorTests/UnresolvedTypeReferenceTests.cs) | - | | ||
|
||
## How to create a symbol | ||
|
||
Checklist: | ||
|
||
- [ ] Write a short description of what this symbol does in the above list. | ||
- [ ] Add the symbol to Silk.NET.SilkTouch.Symbols | ||
- [ ] Add a partial of SymbolVisitor to below the definition, and add visiting method in there. | ||
- [ ] Call the new visiting method either from | ||
- The root Visit(Symbol) method, this should rarely be needed | ||
- The parent's visit method | ||
- [ ] Add Tests to Silk.NET.SilkTouch.Symbols.Tests for | ||
- [ ] The type being visited with it's own visiting method | ||
- [ ] The type being visited with it's parent (not needed if this is a new root type, with no parent) | ||
- [ ] Each part being visited correctly. Only shallowly check this, don't check parts of parts. | ||
- [ ] Handle symbol in Silk.NET.SilkTouch.Emitter | ||
- [ ] Add Tests to Silk.NET.SilkTouch.Emitter.Tests | ||
- [ ] Transforming a sample Symbol matching a specific string | ||
- [ ] Other tests, this is highly dependend on how complex the C# output looks like | ||
- [ ] More is better! | ||
- [ ] You're done. Feel free to use the symbol wherever needed. Prefer to add usages in a separate PR. |
Oops, something went wrong.