All Projects → 71 → Cometary

71 / Cometary

Licence: MIT license
Roslyn extensions, with a touch of meta-programming.

Programming Languages

C#
18002 projects
powershell
5483 projects

Projects that are alternatives of or similar to Cometary

Meziantou.analyzer
A Roslyn analyzer to enforce some good practices in C#.
Stars: ✭ 189 (+509.68%)
Mutual labels:  roslyn, analyzer
Dotnetomdgenerator
A Roslyn-based cross-platform tool that generates an object model diagram from a set of C# source files or assemblies
Stars: ✭ 160 (+416.13%)
Mutual labels:  roslyn, analyzer
doteasy.rpc
Inspired by microservices, a lightweight framework that looks like a rabbit, based on NET Core 2.0 Standard 2 core library
Stars: ✭ 62 (+100%)
Mutual labels:  roslyn, netcore
Norns
dotnet core aop static weaving on roslyn
Stars: ✭ 23 (-25.81%)
Mutual labels:  roslyn, netcore
Platform Compat
Roslyn analyzer that finds usages of APIs that will throw PlatformNotSupportedException on certain platforms.
Stars: ✭ 250 (+706.45%)
Mutual labels:  roslyn, netcore
Pluginframework
Everything is a Plugin in .NET
Stars: ✭ 197 (+535.48%)
Mutual labels:  roslyn, netcore
Security Code Scan
Vulnerability Patterns Detector for C# and VB.NET
Stars: ✭ 550 (+1674.19%)
Mutual labels:  roslyn, analyzer
Seriloganalyzer
Roslyn-based analysis for code using the Serilog logging library. Checks for common mistakes and usage problems.
Stars: ✭ 214 (+590.32%)
Mutual labels:  roslyn, analyzer
audio-tag-analyzer
Extracts metadata music metadata found in audio files
Stars: ✭ 18 (-41.94%)
Mutual labels:  meta, analyzer
Analyzers
C# code analyzers
Stars: ✭ 18 (-41.94%)
Mutual labels:  roslyn, analyzer
Awesome-meta-tags
📙 Awesome collection of meta tags
Stars: ✭ 18 (-41.94%)
Mutual labels:  meta
Kendo.DynamicLinqCore
KendoNET.DynamicLinq implements server paging, filtering, sorting, grouping, and aggregating to Kendo UI via Dynamic Linq for .Net Core App(1.x ~ 3.x).
Stars: ✭ 36 (+16.13%)
Mutual labels:  netcore
mp4analyser
mp4 file analyser written in Python
Stars: ✭ 50 (+61.29%)
Mutual labels:  analyzer
WikiChron
Data visualization tool for wikis evolution
Stars: ✭ 19 (-38.71%)
Mutual labels:  analyzer
aliyun-openapi-sdk-net-core
aliyun open api sdk for .net core 2.0
Stars: ✭ 17 (-45.16%)
Mutual labels:  netcore
less-mix
LESS-Mix - is a functional, powerful and convenient library LESS-mixins.
Stars: ✭ 22 (-29.03%)
Mutual labels:  mixins
statiq-starter-kontent-lumen
Lumen is a minimal, lightweight, and mobile-first starter for creating blogs using Statiq and Kontent by Kentico.
Stars: ✭ 22 (-29.03%)
Mutual labels:  netcore
Unchained
A fully type safe, compile time only units library.
Stars: ✭ 70 (+125.81%)
Mutual labels:  meta-programming
rupture-sass
Better media queries mixins library for SASS
Stars: ✭ 47 (+51.61%)
Mutual labels:  mixins
Zilon Roguelike
Survival roguelike game with huge world generation.
Stars: ✭ 18 (-41.94%)
Mutual labels:  netcore

Cometary

Cometary is a C# project that aims to bring compiler plugins and meta-programming to the C# world.

Thanks to Cometary, the next snippet is valid C# code.

// Emit CIL instructions inline.
IL.Ldnull();
IL.Ret();

// Mixins.
int i = 0;
"i++".Mixin(); // i == 1

// Macros.
Requires.NotNull(parameter);
// .. will be replaced by ..
if (parameter == null)
    throw new ArgumentNullException(nameof(parameter));
    
// Much, much more.

Issues License Lines of Code.

Note
This project is still in active development, and is extremely unstable. Please proceed with caution.

Get started

Cometary requires two core components to work normally:

  • The Analyzer, required to extend the Roslyn build process.
  • The Core library, on which the Analyzer depends.

They can be installed via the NuGet package manager.

Install-Package Cometary.Core Cometary.Analyzer

Once installed, all you have to do is build your project normally (via csc, dotnet build or Visual Studio), and Cometary takes care of the rest.

You now have the required dependencies, but nothing much will change. You need to either install an extension, or make your own.

Note:
To build your own extension, the analyzer is not required, but Cometary will not be executed on your extension.

Installing existing extensions

Some existing extensions can be found in the "src" directory, and installed through the NuGet package manager. Please consult their respective READMEs to learn how to install and use them.

By convention, extensions must be installed as a dependency, and configured properly using attributes. For example, an extension would be registered with the following syntax:

[assembly: Foo(Bar = true)]

Existing extensions

  • Cometary.Metaprogramming, which will run extensions directly defined in your assembly. It allows an assembly to edit its own syntax and resulting compilation before being emitted by Roslyn.
  • Cometary.IL, which will allow you to print your own IL code inline, and modify the way Roslyn emits your code.
  • Cometary.Debugging, which attempts to make the debugging experience flawless, by creating executables that reproduce the whole modification process in a debugger-friendly environment, and printing modified syntax trees to temporary files, for matching sequence points.
  • Cometary.Macros, which allows the use of macros, special methods that edit their own syntax depending on the context of the caller.
  • Cometary.Composition, which brings true composition to the C# language.

Making your own extension

An extension is a normal .NET library that defines one or more CompilationEditors (an example is available below). However, simply having a dependency on the extension is not enough to install it. You also need to create an attribute inheriting CometaryAttribute, and have the user set it on its assembly.

Don't worry, it's easy.

1. Define a CompilationEditor

Create a class that inherits CompilationEditor:

using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Diagnostics;
using Cometary;

/// <summary>
///   <see cref="CompilationEditor" /> that adds the 'Answers' static class to
///   assemblies it edits.
/// </summary>
internal sealed class DeepThoughtEditor : CompilationEditor
{
    public string Namespace { get; }
    
    public DeepThoughtEditor(string @namespace)
    {
        Namespace = @namespace;
    }
  
    /// <inheritdoc />
    protected override void Initialize(CSharpCompilation compilation, CancellationToken cancellationToken)
    {
        CompilationPipeline += EditCompilation;
    }

    /// <summary>
    ///   Edits the given <paramref name="compilation"/>, adding a <see cref="CSharpSyntaxTree"/>
    ///   defining the 'Answers' class.
    /// </summary>
    private CSharpCompilation EditCompilation(CSharpCompilation compilation, CancellationToken cancellationToken)
    {
        if (this.State == CompilationState.End)
            return compilation;

        var tree = SyntaxFactory.ParseSyntaxTree(@$"
            namespace {Namespace} {
                public static class Answers {
                    public static int LifeTheUniverseAndEverything => 42;
                }
            }
        ");

        return compilation.AddSyntaxTrees(tree);
    }
}

2. Define a configuration attribute

Create an attribute that inherits CometaryAttribute:

using System;
using Cometary;

[AttributeUsage(AttributeTargets.Assembly)]
public sealed class DeepThoughtAttribute : CometaryAttribute
{
    public string Namespace { get; }
    
    public DeepThoughtAttribute(string @namespace)
    {
        Namespace = @namespace;
    }
    
    public override IEnumerable<CompilationEditor> Initialize()
    {
        yield return new DeepThoughtEditor(Namespace);
    }
}

3. Build the library, and use it

In any assembly that references the previously defined assembly, add the following code at the top level of a file:

[assembly: DeepThought("TestAssembly")]

Since the library modifies the build process, not only will the Answers class be defined in the output, it can also be used!

Assert.Equal(Answers.LifeTheUniverseAndEverything, 42); // will not throw.

However, the IDE intergration isn't perfect, and an error will be shown while editing. During compilation, though...

Build succeeded.
    0 Warning(s)
    0 Error(s)

Compatibility

  • The analyzer is available for Roslyn 2.0.0 and up (VS 2017 and up), and works with dotnet and csc, as long as they use a recent version of Roslyn. However, right now, Visual Studio cannot load all assemblies required by the analyzer and, as such, cannot build projects that depend on it. A workaround is:
    1. Open a command prompt in your project directory.
    2. Build or run the project in Visual Studio; one or more errors will be shown.
    3. In the command prompt, type dotnet build, no errors should be shown (at least not from Cometary).
    4. Run the project again in Visual Studio. This time, it should load the file output by the previous command, and start immediately.
  • Cometary.Core and other extensions are available for .NET Standard 1.4 and up.
  • Cometary.Metaprogramming is available for .NET Standard 1.5 and up.
  • For building, Visual Studio 2017 with the Scry extension is required.

Testing

Tests are available in the test directory, and contain some examples of what can be easily achieved using Cometary. They all all three different configurations, depending on what we're trying to achieve:

  • Release: Ensure tests do well in an optimized environment, and don't debug anything.
  • Debug: Use Cometary.Debugging to debug the modification process related to the tested extension.
  • Test: Run the tests on a debugger-friendly environment, after modifying the assembly through Cometary.

How does it work?

  • When loaded, the Analyzer loads the Cometary.Core library (optionally resolving dependencies thanks to the references of the compilation it analyzes).
  • When Cometary.Core is loaded, some hooks are created (using Ryder, via the Hooks class). Those hooks redirect calls made to some internal Roslyn methods, to custom methods.
  • When a CSharpCompilation is about to be emitted (via CheckOptionsAndCreateModuleBuilder), Cometary intercepts the call and does the following things:
    1. Create a CompilationProcessor and bind it to the CSharpCompilation.
    2. Find all attributes set on the assembly to emit that inherit CometaryAttribute, and initialize them. During initialization, those attributes have the ability to register CompilationEditors.
    3. All registered editors are initialized in their turn, allowing them to suppress Diagnostics (by registering a Predicate<Diagnostic>), or edit the compilation, and its syntax and symbols.
    4. Let all the now-initialized editors actually edit the original CSharpCompilation.
    5. Return the modified CSharpCompilation, and dispose of all the editors and attributes. However, since the hooked method isn't static, a different object cannot be used to emit the assembly. As a workaround, all fields from the modified CSharpCompilation are copied to the original one.
  • The emission process goes back to its normal flow with the modified CSharpCompilation.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].