Coder Social home page Coder Social logo

syndiesis's Introduction

Syndiesis

The most revolutionary syntax visualizer for C#

Motivation

The project was inspired by the task for applying into a Roslyn internship position regarding C# syntax highlighting at JetBrains: (project / task)

The main design inspiration is SharpLab. The syntax view feature of SharpLab is the main design that the app built upon.

Despite not applying for the internship, I wanted to finish the project and release it into a usable state without entering the depths of feature creep.

Usage

For Windows, download from the Releases page. For macOS and Linux, you have to manually compile the program (refer to the section below).

The program is designed to be cross-platform for desktop (including Windows, Linux and macOS). It's heavily tested to run on Windows 10, and it's moderately tested on Windows 11 and macOS. Please file an issue if platform-specific problems occur.

Check the change log here.

View the wiki for detailed documentation.

Compiling

To compile this program you will need an IDE like Visual Studio 2022, or JetBrains Rider 2024.1. Load the solution file (Syndiesis.sln) from the IDE of your choice and build the project (recommended to switch to Release mode).

Demo

The video was shot in version 1.1.0

Syndiesis.1.1.0.demo.mp4

Stack

Dependencies

Features

Below is a short list of features:

  • Code editor
    • AvaloniaEdit's features
    • Syntax and semantic colorization
    • Go to definition using F12
    • Custom nagivation to outer syntax nodes based on the current selection
  • Syntax and semantic analysis visualizer
    • Current caret syntax node highlighting
    • Tree view of nodes
    • Display of property names of syntax objects
    • Colorful display of different analysis list view nodes
    • Navigation to code snippet span of selected node
    • Syntax, symbol and operation analysis
    • Indication of throwing properties per node
    • Loading nodes respects responsiveness of the app

A large portion of the app is built using basic components in Avalonia. The code editor is from AvaloniaEdit. Some icons were taken from the free version of FontAwesome.

Any issues regarding the code editor are most likely to be reported in AvaloniaEdit. This includes behavior not specific to Syndiesis. Issues will be closed if they are specific to AvaloniaEdit, and must be reported there.

Desired features

Desired features among other issues are listed in the issues.

Ruled-out features

  • Auto-complete on text

Design philosophy

The syntax visualizer should provide detailed information about how Roslyn parses the given C# code snippet, and in a pretty and user-friendly format. SharpLab lacks in readability of the tree, and it also doesn't paint the entire picture as intended.

The properties of the nodes are automatically extracted via reflection. Some are filtered out due to duplication in most cases, and in other cases they were not providing any helpful information.

Each different node type is differently treated to extract the most useful information out of it. If you encounter a node missing critical information, or displaying it weirdly, please file an issue.

With 1.1.0 onwards, the program's direction was shifted more towards explaining and visualizing the expected results by using Roslyn itself. This expands the initial scope of the program into being a handy utility making the usage of Roslyn more predictable, especially when testing analyzers or source generators.

syndiesis's People

Contributors

elvodqa avatar rekkonnect avatar wieslawsoltes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

syndiesis's Issues

Copy content in syntax tree view

The syntax tree view is read-only and the user has no way to copy the contents.

Design

  • Right-clicking with Ctrl will copy the entire node line's contents.
  • Right-clicking with Ctrl+Shift will copy a copyable part of the node line's contents.

Copyable parts will be declared alongside the displayed runs of text. A copyable part may consist of multiple displayed runs, like the color formatting applied to types like SyntaxList and the alike.

A toast notification will inform the user that the text was copied, also showing the copied text.

Truncated text will be copied in its entirety.

Analysis tree nodes with overlapping spans hinder discoverability

When multiple analysis tree nodes under the same parent have overlapping document spans, they are resolved by picking the first one containing the desired position. This leads to omitting more specialized nodes under the same parent that have a shorter span.

The resolver should evaluate all children nodes and pick the one whose document span is the shortest and also covers the desired position.

Handle empty tokens better

Consider the following example:
image

OmittedArraySizeExpressionToken has an empty string as text, and no surrounding trivia attached to it, but the node is expandable. It's also not explicitly shown whether its text is empty.

Move cursor to syntax tree node position

Design

  • Right-clicking disables the current behavior (toggling expansion of tree node children)
  • Right-clicking with Ctrl on a syntax tree node places the cursor at the start of the node's span
  • Right-clicking with Ctrl+Shift on a syntax tree node also selects the span of the node, placing the cursor at the start of the node's span

If the tree node has no span by itself, find its parent's span recursively. If no ancestor has a span, do nothing.

F12 to navigate to definition of hovered symbol

If there is no symbol to navigate to, pulse the background of the code editor with a red color to indicate failure.

Otherwise, move to the first declaration of the symbol and select the text span representing the identifier of the declared symbol.

Handle Attribute operations and AttributeData in a separate view dedicated to attributes

Attributes are not discoverable by any operation in the operation tree. And in the symbols view, attributes can be cluttered among other symbols.

Attributes for top-level members like top-level class declarations, or assembly/module attributes do appear in the operations view. We will remove them from there temporarily, until the new view comes in.

A new Attributes view will be implemented which will focus on attributes specifically and display them grouped by symbol. Nested symbols will also appear with proper nesting, i.e. method symbols will be contained within their containing type symbols, local function symbols will be contained within their declaring method symbols, etc.

Large code performance hits

Testing with large files (20k LoC -- example) can cause the following problems:

  • Moving the cursor around on any view causes massive stutters due to large node counts
  • Typing creates unnecessary string instances to pass as the resulting string for analysis, resulting in lag on every keystroke after a certain point

Hovering over nodes with deep nesting lags

Traversing through a very deep tree is very expensive, consider storing all the lines in a list, optionally caring about keeping it ordered (if necessary)

Note that the lag only occurs when the hovered nodes are very deep in the tree, nodes higher in the tree don't appear as laggy.

Bad cursor movement on deleting line break

Summary

Deleting line break on a line with content moves the cursor to the end of the previous line, after the content of both lines that were merged.

Example

Assume that $$ denotes the position of the cursor.

Previous:

public static void Main(string[] args)
{
$$    Console.WriteLine();
}

After deleting:

public static void Main(string[] args)
{    Console.WriteLine();$$
}

Expected:

public static void Main(string[] args)
{$$    Console.WriteLine();
}

Code editor syntax highlighting

The code editor can receive a syntax highlighting buff. However, we won't speculatively update the highlighting live until another pass.

While typing, the characters that were already there will preserve their original highlighting until the analysis is performed. The inserted characters will not be highlighted until the pass is done. Removing characters will adjust the highlighting of existing characters correspondingly.

The syntax highlighting can be split into two stages, one syntactic and one semantic. The semantic pass will show more information about identifiers that are not already classified. Declared symbols can be semantically analyzed in the syntactic pass since we already know their classification from their syntax parents.

During both passes, the code editor lines will be invalidated regionally, and the updating will happen by using channels, to reduce the overhead of the semantic analysis.

Auto indentation on new line

Adding new lines does not automatically insert expected indentation. The editor should prefer the deepest indentation on the nearby lines. It does not have to be sophisticated.

More and better shortcuts

  • Cut text using Ctrl+X
  • Apply cut and copy to current line when no text is selected
  • Select word with Ctrl+W
  • Expand selection span to nearest syntactic node with Ctrl+U

New view for interactive analysis of individual nodes based on caret selection

Summary

Create a view that will display only select properties and methods of the currently selected syntax object (node, token or trivia)

Motivation

The project began as a syntax tree viewer, which was later expanded into supporting displaying symbols and operations. However, the implementation was driven by the constraint for a tree-like view. This constraint poses problems for the usability and predictability of the feature.

The main goal is explorability and direct listing of the objects that may be returned. However, such a view hides away the clue of the path to the displayed object, and also doesn't show all the available children if they're not contained in the result returned from Roslyn. Not to mention that operations needed a custom OperationTree which bundles operations under the umbrella of every top-level symbol that contains the first operation.

Details

The new view will be based on this skeleton example:

Current node:
N    ClassDeclarationSyntax

Parent: FileScopedNamespaceDeclarationSyntax

Properties:
...

(expandable)
+ ChildNodes():   IEnumerable<SyntaxNode>
+ ChildTokens():   IEnumerable<SyntaxNode>
+ ChildNodesAndTokens():   IEnumerable<SyntaxNode>

+ SemanticModel.GetSymbolInfo(this): ...
+ SemanticModel.GetTypeInfo(this): ...
+ SemanticModel.GetAliasInfo(this): ...
+ SemanticModel.GetPreprocessingSymbolInfo(this): ...
+ SemanticModel.GetSpeculativeSymbolInfo(this): ...
+ SemanticModel.GetSpeculativeTypeInfo(this): ...
+ SemanticModel.GetSpeculativeAliasInfo(this): ...

+ SemanticModel.GetOperation(this):   IOperation

This is more to the point, and provides a raw introspection of the expected results. This makes Syndiesis a much stronger Roslyn playground with many built-in conveniences for a test workflow. The most important aspect is giving a direct mapping of the information at hand with the expected outcome, which will be helpful to determine the information to expect when building a Roslyn tool.

The already existing views of symbols and operations won't be removed, but will be less likely to see improvements after the introduction of this view.

Show diagnostics

Diagnostics should be shown. When hovered above a position in the document for a period of time, a popup will show the diagnostics that exist on that place, or none if none exists. Hover duration will be a customizable option.

Improve display value of token

There are some cases where the current display value is confusing, or unclear. For example, NumericLiteralToken displays the numeric value of the token, disregarding the original format of the token., as shown below:

image

While the documentation clearly states that this is the value returned from the ValueText property, there are 3 properties about getting a representation of a token: Text, Value and ValueText. In cases like numeric literals and string literals, the returned values are not identical. The recommended approach is to include a D node for every one of those 3 properties. null values should be explicitly shown and highlighted accordingly to avoid confusing with an actual null string literal.

Tree analysis improvements

Currently, we only show the syntax view of the given code. Users might want to inspect the operations tree, or the semantic declarations tree. This will introduce a group of options to show near the tree view.

Add Cancel and Reset buttons in settings

Requested by @elvodqa

Pressing Cancel will revert the current settings to their previous state, and exit the settings menu.

Pressing Reset will reset the settings to their current values in the file, by force reloading from the file. The settings menu will remain open, and the values will be updated on the spot.

Code editor improvements around Tab

  • Tab is only used to insert spaces. There is no way to reduce indentation on the currently hovered line, or the range of selected lines.
  • The program has a strong preference for the indentation of 4 spaces. The settings should allow customizing that.

Avoid collapsing parent node with Collapse all button

Collapsing all the way to CompilationUnitSyntax is unnecessary and often the user will end up expanding it manually. We should avoid that.

Edit: This also applies to any root node that is expandable. This includes OperationTree, IAssemblySymbol, etc. This is not bound to the type of the value represented by the node, but rather on whether it's a root or not.

Insert mode in code editor

Pressing the Insert key will toggle between insert or overwrite text mode.

In insert mode, the cursor will be as thick as the current character. Entering text will replace the currently hovered character's value, instead of inserting text. If the cursor's character position is beyond the line's end, the text will be inserted instead.

After moving to AvaloniaEdit, we will wait for until it gets insert mode. This issue is just for tracking purposes.

Clipboard paste fails on macOS

Clipboard paste fails when there is no code editor tag assigned to the clipboard data object. This happens on macOS, and perhaps other platforms.

Credits to @elvodqa for discovering this

Support VB

Supporting VB is not too hard. The program should also automatically detect the language of the document.

Automatic detection ideas:

  • Parse and traverse entire trees, compare number of SkippedTokenTrivia occurrences
  • Discover common syntax nodes per language, like imports/declarations/keywords

Toggling fullscreen does not correctly update max width of syntax tree view nodes

While other means of resizing work, like resizing from the grid splitter in the middle, snapping the window to the entire screen does not trigger a resize of the nodes' widths, displaying a background highlighting shorter than the available width. This is probably an Avalonia bug, and we could wait until it gets fixed. This was not an Avalonia bug.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.