ILSourceParser 1.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package ILSourceParser --version 1.1.0                
NuGet\Install-Package ILSourceParser -Version 1.1.0                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ILSourceParser" Version="1.1.0" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ILSourceParser --version 1.1.0                
#r "nuget: ILSourceParser, 1.1.0"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ILSourceParser as a Cake Addin
#addin nuget:?package=ILSourceParser&version=1.1.0

// Install ILSourceParser as a Cake Tool
#tool nuget:?package=ILSourceParser&version=1.1.0                

ILSourceParser

This library for .NET provides functionality to parse IL source code. If you're not aware, Microsoft Intermediate Language (IL or CIL, formerly known as MSIL) is what the .NET application typically consists of. C#, Visual Basic, F#, and other well-known official .NET languages compile to IL bytecode. However, IL actually has its syntax as well. ILSourceParser parses the IL syntax into syntax nodes, making it easier to analyze IL.

This library does not rely on any existing project and is not a port from another language, so there could be some issues with this library. If you encounter one, please create a new issue post about it!

The known issue is that ILSourceParser might not be the fastest thing in the world, because it took nearly 1 second to analyze a 200-line of code IL file. Maybe it just needs some additional JIT warming, although there could be a different reason - parsing IL is generally harder than parsing C#, mostly because IL has almost 300 instructions, and we have to do over 300 checks when parsing method body to parse one instruction.

Example

var syntaxTree = ILSyntaxTree.ParseText(@".assembly MyAssembly { }");
var root = syntaxTree.GetRoot();
foreach (SyntaxNode node in root.DescendantNodes)
{
    // do something with node
}

A more complex example here:

using ILSourceParser;
using ILSourceParser.Syntax;
using ILSourceParser.Syntax.Instructions;
using Sprache;

string input = @".assembly MyAssembly
{
    .ver 1:2:3:4
}
.assembly extern System.Runtime
{
}
.assembly extern System.Console
{
}

// My Cool Application !

.imagebase 0x00400000
.line 123

.class public sequential auto ansi beforefieldinit MyValueType extends [System.Runtime]System.ValueType
{
    .field private static initonly string s_myString

    .method public static hidebysig void .cctor() cil managed
    {
        ldstr ""Hello, World!""
        stsfld string MyValueType::s_myString
    }
    
    .method public static void PrintText() cil managed
    {
        .maxstack 8
        
        ldsfld string MyValueType::s_myString
        call void [System.Console]System.Console::WriteLine(string)
        
        ret
    }
}";
var syntaxRoot = ILSyntaxTree.ParseText(input).GetRoot();

foreach (var descendant in syntaxRoot.DescendantNodes)
{
    switch (descendant)
    {
        case AssemblyDeclarationSyntax asm:
            Console.WriteLine($"Assembly {asm.AssemblyName}, is external: {asm.IsExtern}");
            break;
        case BaseCommentSyntax comment:
            if (comment is InlineCommentSyntax inline)
            {
                Console.WriteLine($"Inline comment, text: {inline.CommentText}");
            }
            else if (comment is MultilineCommentSyntax multiline)
            {
                Console.WriteLine($"Multiline comment, text: {multiline.CommentText}");
            }
            break;
        case ImageBaseDirectiveSyntax imageBase:
            Console.WriteLine($"Image base {imageBase.ImageBase}");
            break;
        case LineDirectiveSyntax line:
            Console.WriteLine($"Line {line.Line}");
            break;
        case ClassDeclarationSyntax @class:
            string flags = string.Join(", ", @class.Flags);
            Console.WriteLine($"Class named {@class.Name}; flags: {flags}");
            break;
    }
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.3.0 84 7/31/2024
1.2.1 87 7/25/2024
1.2.0 87 7/25/2024
1.1.2 93 7/25/2024
1.1.1 81 7/24/2024
1.1.0 85 7/24/2024
1.0.0 96 7/23/2024

1. Added new feature to parse .try/finally blocks
2. Fixed bug where generic parameters that are primitive types like int32, and generic parameters that are
generic parameter references like !T, will always result in GenericParameterTypeConstraintSyntax instead of
GenericParameterPrimitiveSyntax and GenericParameterReferenceSyntax respectively
3. Fixed bug where numbers will always be prefixed with 0x (like "123" => "0x123") even if they don't have the 0x prefix