Skip to content

Basic Emitter/Visitor docs #892

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 19, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions documentation/for-contributors/generators/emitter/visitor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Visitor

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.