├── .vscodeignore ├── src ├── vscodeilviewer │ ├── .gitignore │ ├── logo.png │ ├── CHANGELOG.md │ ├── featureimages │ │ └── demo.gif │ ├── .vscodeignore │ ├── tsconfig.json │ ├── src │ │ ├── IInstructionResult.ts │ │ ├── process.ts │ │ ├── Logger.ts │ │ ├── extension.ts │ │ └── IntermediateLanguageContentProvider.ts │ ├── .vscode │ │ ├── settings.json │ │ ├── launch.json │ │ └── tasks.json │ ├── test │ │ ├── extension.test.ts │ │ └── index.ts │ ├── README.md │ ├── package.json │ └── vsc-extension-quickstart.md ├── IlViewer.Core │ ├── ResultOutput │ │ ├── CompilationErrorType.cs │ │ ├── InspectionError.cs │ │ ├── InstructionResult.cs │ │ └── InspectionResult.cs │ ├── ExampleClass.cs │ ├── InstructionWrapper.cs │ ├── ILDecompiler.cs │ ├── project.json │ ├── WorkspaceManager.cs │ ├── ProjectState.cs │ ├── IlViewer.Core.xproj │ ├── RoslynClass.cs │ ├── CSharpLanguage.cs │ ├── ProjectContextLens.cs │ └── IlGeneration.cs ├── IlViewer.WebApi │ ├── appsettings.json │ ├── Dockerfile │ ├── Models │ │ └── IlRequest.cs │ ├── web.config │ ├── Properties │ │ └── launchSettings.json │ ├── Program.cs │ ├── Controllers │ │ ├── ValuesController.cs │ │ └── IlViewerController.cs │ ├── IlViewer.WebApi.xproj │ ├── project.json │ ├── IlViewer.WebApi.sln │ └── Startup.cs └── IlViewer │ ├── project.json │ ├── IlViewer.xproj │ └── Program.cs ├── images ├── demo.gif ├── logo.png └── logo.psd ├── global.json ├── scripts └── publish.sh ├── .vscode ├── tasks.json └── launch.json ├── LICENSE ├── README.md └── .gitignore /.vscodeignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/vscodeilviewer/.gitignore: -------------------------------------------------------------------------------- 1 | out/ 2 | node_modules/ 3 | server/ -------------------------------------------------------------------------------- /images/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephwoodward/VSCodeILViewer/HEAD/images/demo.gif -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephwoodward/VSCodeILViewer/HEAD/images/logo.png -------------------------------------------------------------------------------- /images/logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephwoodward/VSCodeILViewer/HEAD/images/logo.psd -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src" ], 3 | "sdk": { "version": "1.0.0-preview2-1-003177" } 4 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephwoodward/VSCodeILViewer/HEAD/src/vscodeilviewer/logo.png -------------------------------------------------------------------------------- /src/vscodeilviewer/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## 0.0.1 (January 19, 2017) 4 | - Initial release of IL Viewer for Visual Studio Code. -------------------------------------------------------------------------------- /src/vscodeilviewer/featureimages/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/josephwoodward/VSCodeILViewer/HEAD/src/vscodeilviewer/featureimages/demo.gif -------------------------------------------------------------------------------- /src/IlViewer.Core/ResultOutput/CompilationErrorType.cs: -------------------------------------------------------------------------------- 1 | namespace IlViewer.Core.ResultOutput 2 | { 3 | public enum CompilationErrorType 4 | { 5 | Warning, 6 | Error 7 | } 8 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | .idea 4 | out/test/** 5 | test/** 6 | src/** 7 | **/*.map 8 | .gitignore 9 | tsconfig.json 10 | **/*.ts 11 | vsc-extension-quickstart.md 12 | *.vsix -------------------------------------------------------------------------------- /src/IlViewer.WebApi/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/IlViewer.Core/ResultOutput/InspectionError.cs: -------------------------------------------------------------------------------- 1 | namespace IlViewer.Core.ResultOutput 2 | { 3 | public class InspectionError 4 | { 5 | public string Message { get; set; } 6 | 7 | public CompilationErrorType Type { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/ExampleClass.cs: -------------------------------------------------------------------------------- 1 | namespace IlViewer.Core 2 | { 3 | public class ExampleClass 4 | { 5 | private readonly string _message; 6 | public ExampleClass() 7 | { 8 | _message = "Hello World!"; 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/ResultOutput/InstructionResult.cs: -------------------------------------------------------------------------------- 1 | namespace IlViewer.Core.ResultOutput 2 | { 3 | public class InstructionResult 4 | { 5 | /*public string IlOpCode => ""; 6 | public string IlOperand => "";*/ 7 | public string Value { get; set;} 8 | } 9 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:latest 2 | 3 | COPY . /app 4 | 5 | WORKDIR /app 6 | 7 | RUN ["dotnet", "restore"] 8 | 9 | RUN ["dotnet", "build"] 10 | 11 | EXPOSE 5000/tcp 12 | 13 | ENTRYPOINT ["dotnet", "run", "--server.urls", "http://0.0.0.0:5000"] 14 | -------------------------------------------------------------------------------- /scripts/publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dotnet publish ../src/IlViewer.WebApi -c release --output "../src/vscodeilviewer/server/" 4 | dotnet publish ../src/IlViewer -c debug --output "../src/vscodeilviewer/server/" 5 | 6 | rm src/vscodeilviewer/vscodeilviewer-*.vsix 7 | 8 | cd src/vscodeilviewer/ -------------------------------------------------------------------------------- /src/IlViewer.Core/InstructionWrapper.cs: -------------------------------------------------------------------------------- 1 | using Mono.Cecil.Cil; 2 | 3 | namespace IlViewer.Core 4 | { 5 | public class InstructionWrapper 6 | { 7 | public Instruction Instruction { get; set; } 8 | 9 | public bool HasInstruction => Instruction != null; 10 | } 11 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Models/IlRequest.cs: -------------------------------------------------------------------------------- 1 | namespace IlViewer.WebApi.Models 2 | { 3 | public class IlRequest 4 | { 5 | // Project.json file location 6 | public string ProjectFilePath { get; set; } 7 | // Filename of file user is wishing to inspect 8 | public string Filename { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "." 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test" 15 | ] 16 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/src/IInstructionResult.ts: -------------------------------------------------------------------------------- 1 | interface IInstructionResult { 2 | value : string; 3 | ilOpCode : string; 4 | ilOperand : string; 5 | } 6 | 7 | interface ICompilationError { 8 | message : string; 9 | } 10 | 11 | interface IInspectionResult { 12 | ilResults : IInstructionResult[] 13 | compilationErrors : ICompilationError[] 14 | hasErrors : boolean; 15 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "command": "dotnet", 4 | "isShellCommand": true, 5 | "args": [], 6 | "tasks": [ 7 | { 8 | "taskName": "build", 9 | "args": [ 10 | "${workspaceRoot}/src/IlViewer.WebApi/project.json" 11 | ], 12 | "isBuildCommand": true, 13 | "problemMatcher": "$msCompile" 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/src/process.ts: -------------------------------------------------------------------------------- 1 | import * as child from 'child_process'; 2 | import * as SpawnOptions from 'child_process'; 3 | import { Logger } from './logger'; 4 | 5 | export namespace DecompilerProcess { 6 | 7 | export function spawn(cmd: string, args: string[], logger: Logger, options?) : child.ChildProcess { 8 | logger.appendLine(`Starting server with command: ${cmd}`); 9 | return child.spawn("dotnet", [ cmd ].concat(args), options); 10 | } 11 | 12 | } -------------------------------------------------------------------------------- /src/IlViewer/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "debugType": "portable", 5 | "emitEntryPoint": true, 6 | "outputName": "ilViewer.Console" 7 | }, 8 | "dependencies": {}, 9 | "frameworks": { 10 | "netcoreapp1.1": { 11 | "dependencies": { 12 | "Microsoft.NETCore.App": { 13 | "type": "platform", 14 | "version": "1.1.0" 15 | } 16 | }, 17 | "imports": "dnxcore50" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/vscodeilviewer/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": false // set this to true to hide the "out" folder with the compiled JS files 5 | }, 6 | "search.exclude": { 7 | "out": true // set this to false to include "out" folder in search results 8 | }, 9 | "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version 10 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/IlViewer.Core/ILDecompiler.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Mono.Cecil; 3 | 4 | namespace IlViewer.Core 5 | { 6 | public class IlDecompiler { 7 | public void Decompile(Stream assemblyStream, TextWriter codeWriter) { 8 | var assembly = AssemblyDefinition.ReadAssembly(assemblyStream); 9 | 10 | // var output = new CustomizableIndentPlainTextOutput(codeWriter) { 11 | // IndentationString = " " 12 | // }; 13 | // var disassembler = new ReflectionDisassembler(new ILCommentingTextOutput(output, 30), false, new CancellationToken()); 14 | // disassembler.WriteModuleContents(assembly.MainModule); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "debugType": "portable" 5 | }, 6 | "dependencies": { 7 | "Microsoft.CodeAnalysis.CSharp.Workspaces": "1.3.2", 8 | "Microsoft.DotNet.ProjectModel": "1.0.0-rc3-1-003177", 9 | "Microsoft.DotNet.ProjectModel.Workspaces": "1.0.0-preview2-1-003177", 10 | "Microsoft.Extensions.Logging": "1.0.0", 11 | "Microsoft.Extensions.Logging.Console": "1.0.0", 12 | "Microsoft.Extensions.Logging.Debug": "1.0.0", 13 | "Mono.Cecil": "0.10.0-beta1-v2", 14 | "System.ValueTuple": "4.3.0-preview1-24530-04", 15 | "System.Reflection.Metadata": "1.4.1", 16 | "Microsoft.CSharp": "4.3.0" 17 | }, 18 | "frameworks": { 19 | "netcoreapp1.0": { 20 | "imports": "portable-net45+win8+wp8+wpa81" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:1479/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "IlViewer.WebApi": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "http://localhost:5000/api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/vscodeilviewer/test/extension.test.ts: -------------------------------------------------------------------------------- 1 | // 2 | // Note: This example test is leveraging the Mocha test framework. 3 | // Please refer to their documentation on https://mochajs.org/ for help. 4 | // 5 | 6 | // The module 'assert' provides assertion methods from node 7 | import * as assert from 'assert'; 8 | 9 | // You can import and use all API from the 'vscode' module 10 | // as well as import your extension to test it 11 | import * as vscode from 'vscode'; 12 | import * as myExtension from '../src/extension'; 13 | 14 | // Defines a Mocha test suite to group tests of similar kind together 15 | suite("Extension Tests", () => { 16 | 17 | // Defines a Mocha unit test 18 | test("Something 1", () => { 19 | assert.equal(-1, [1, 2, 3].indexOf(5)); 20 | assert.equal(-1, [1, 2, 3].indexOf(0)); 21 | }); 22 | }); -------------------------------------------------------------------------------- /src/IlViewer.Core/ResultOutput/InspectionResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | 4 | namespace IlViewer.Core.ResultOutput 5 | { 6 | public class InspectionResult 7 | { 8 | public InspectionResult() 9 | { 10 | IlResults = new List(); 11 | CompilationErrors = new List(); 12 | } 13 | 14 | public IList IlResults { get; set; } 15 | 16 | public IList CompilationErrors { get; } 17 | 18 | public bool HasErrors => CompilationErrors.Any(); 19 | 20 | public void AddError(string errorMessage) 21 | { 22 | CompilationErrors.Add(new InspectionError 23 | { 24 | Message = errorMessage 25 | }); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.Extensions.Configuration; 6 | 7 | namespace IlViewer.WebApi 8 | { 9 | public class Program 10 | { 11 | public static void Main(string[] args) 12 | { 13 | //Console.WriteLine("Arg" + args[1]); 14 | var config = new ConfigurationBuilder() 15 | //.AddCommandLine(Environment.GetCommandLineArgs().Skip(1).ToArray()) 16 | .Build(); 17 | 18 | var host = new WebHostBuilder() 19 | .UseConfiguration(config) 20 | .UseKestrel() 21 | .UseContentRoot(Directory.GetCurrentDirectory()) 22 | .UseStartup() 23 | .UseUrls("http://localhost:65530") 24 | .Build(); 25 | 26 | host.Run(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/IlViewer.Core/WorkspaceManager.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.DotNet.ProjectModel.Workspaces; 4 | 5 | namespace IlViewer.Core 6 | { 7 | public static class WorkspaceManager 8 | { 9 | public static Compilation LoadWorkspace(string filePath) 10 | { 11 | var projectWorkspace = new ProjectJsonWorkspace(filePath); 12 | 13 | var project = projectWorkspace.CurrentSolution.Projects.FirstOrDefault(); 14 | var compilation = project.GetCompilationAsync().Result; 15 | 16 | /*foreach (var tree in compilation.SyntaxTrees) 17 | { 18 | var source = tree.GetRoot().DescendantNodes(); 19 | var classDeclarations = source.OfType().Where(x => x.Identifier.Text.Contains("MessagingConfig")).ToList(); 20 | if (classDeclarations.Any()) 21 | { 22 | 23 | } 24 | }*/ 25 | 26 | return compilation; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.AspNetCore.Mvc; 3 | 4 | namespace IlViewer.WebApi.Controllers 5 | { 6 | [Route("api/[controller]")] 7 | public class ValuesController : Controller 8 | { 9 | // GET api/values 10 | [HttpGet] 11 | public IEnumerable Get() 12 | { 13 | return new string[] { "value1", "value2" }; 14 | } 15 | 16 | // GET api/values/5 17 | [HttpGet("{id}")] 18 | public string Get(int id) 19 | { 20 | return "value"; 21 | } 22 | 23 | // POST api/values 24 | [HttpPost] 25 | public void Post([FromBody]string value) 26 | { 27 | } 28 | 29 | // PUT api/values/5 30 | [HttpPut("{id}")] 31 | public void Put(int id, [FromBody]string value) 32 | { 33 | } 34 | 35 | // DELETE api/values/5 36 | [HttpDelete("{id}")] 37 | public void Delete(int id) 38 | { 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/IlViewer.Core/ProjectState.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.DotNet.ProjectModel; 4 | 5 | namespace IlViewer.Core 6 | { 7 | public class ProjectState 8 | { 9 | public ProjectState(ProjectId id, ProjectContext context) 10 | { 11 | Id = id; 12 | ProjectContext = context; 13 | } 14 | 15 | public ProjectId Id { get; } 16 | 17 | public ProjectContext ProjectContext { get; set; } 18 | 19 | public Dictionary FileMetadataReferences { get; } = new Dictionary(); 20 | 21 | public Dictionary ProjectReferences { get; } = new Dictionary(); 22 | 23 | public Dictionary DocumentReferences { get; } = new Dictionary(); 24 | 25 | public override string ToString() 26 | { 27 | return $"[{nameof(ProjectState)}] {ProjectContext.ProjectFile.Name}/{ProjectContext.TargetFramework}"; 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/test/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Joseph Woodward 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/vscodeilviewer/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.1.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outFiles": [ "${workspaceRoot}/out/src/**/*.js" ], 14 | "preLaunchTask": "npm" 15 | }, 16 | { 17 | "name": "Launch Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outFiles": [ "${workspaceRoot}/out/test/**/*.js" ], 25 | "preLaunchTask": "npm" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/vscodeilviewer/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /src/IlViewer/IlViewer.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | {344099AB-5007-45B9-8CBA-731FBA166C21} 11 | IlViewer 12 | .\obj 13 | .\bin\ 14 | v4.5.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/IlViewer.Core/IlViewer.Core.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | {0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0} 11 | IlViewer.Core 12 | .\obj 13 | .\bin\ 14 | v4.5.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/IlViewer.WebApi/IlViewer.WebApi.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | {A10630E4-1C3C-473B-A64A-6776FF68A1D1} 11 | IlViewer.WebApi 12 | .\obj 13 | .\bin\ 14 | v4.5.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/vscodeilviewer/src/Logger.ts: -------------------------------------------------------------------------------- 1 | export class Logger { 2 | private _writer: (message: string) => void; 3 | private _prefix: string; 4 | 5 | private _indentLevel: number = 0; 6 | private _indentSize: number = 4; 7 | private _atLineStart: boolean = false; 8 | 9 | constructor(writer: (message: string) => void, prefix?: string) { 10 | this._writer = writer; 11 | this._prefix = prefix; 12 | } 13 | 14 | private _appendCore(message: string): void { 15 | if (this._atLineStart) { 16 | if (this._indentLevel > 0) { 17 | const indent = " ".repeat(this._indentLevel * this._indentSize); 18 | this._writer(indent); 19 | } 20 | 21 | if (this._prefix) { 22 | this._writer(`[${this._prefix}] `); 23 | } 24 | 25 | this._atLineStart = false; 26 | } 27 | 28 | this._writer(message); 29 | } 30 | 31 | public append(message?: string): void { 32 | message = message || ""; 33 | this._appendCore(message); 34 | } 35 | 36 | public appendLine(message?: string): void { 37 | message = message || ""; 38 | this._appendCore(message + '\n'); 39 | this._atLineStart = true; 40 | } 41 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/README.md: -------------------------------------------------------------------------------- 1 | # IL Viewer for Visual Studio Code 2 | 3 | IL (Intermediate Language) Viewer for Visual Studio Code allows you to rapidly inspect the IL output of any given C# file. 4 | 5 | **How does it work?** 6 | Using the power of Roslyn, IL Viewer compiles your chosen file in memory (along with any dependencies it has) and produces an in memory DLL containing the IL. 7 | 8 | ## Features 9 | 10 | **Easy IL Inspection:** 11 | 12 | Simply open a .cs file which you'd like to inspect, right-click and select `Inspect IL`. 13 | 14 | ![Easy IL inspection](https://raw.githubusercontent.com/JosephWoodward/VSCodeILViewer/master/images/demo.gif) 15 | 16 | More features coming soon. 17 | 18 | 19 | ## Requirements 20 | 21 | Currently only works on .NET Core apps using project.json. Support for .csproj is coming very soon. 22 | 23 | ## Known Issues 24 | 25 | - In order to refresh IL output you need to close the split pane and request IL again. 26 | - Delay in first de-compilation start up, this will be improved soon. 27 | - Project.json support only (.csproj coming soon) 28 | 29 | ## Release Notes 30 | 31 | ### 0.0.1 32 | 33 | Initial release of IL Viewer. Please report any issues you find to [https://github.com/JosephWoodward/VSCodeILViewer/](https://github.com/JosephWoodward/VSCodeILViewer/) -------------------------------------------------------------------------------- /src/IlViewer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Text; 6 | using System.Threading; 7 | 8 | namespace IlViewer 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | /*var argsList = new List(args); 15 | if (argsList.Contains("--debug")) 16 | { 17 | argsList.Remove("--debug"); 18 | Console.WriteLine($"2Attach debugger to process {Process.GetCurrentProcess().Id} to continue. .."); 19 | 20 | 21 | Thread.Sleep(8000); 22 | Console.WriteLine("8 seconds later..."); 23 | while (!Debugger.IsAttached) 24 | { 25 | Thread.Sleep(100); 26 | } 27 | }*/ 28 | 29 | Thread.Sleep(3000); 30 | //Console.WriteLine("8 seconds later..."); 31 | 32 | using (var stdin = Console.OpenStandardInput()) 33 | using (var stdout = Console.OpenStandardOutput()) 34 | { 35 | Console.WriteLine("Hello World"); 36 | 37 | var buffer = new byte[2048]; 38 | int bytes; 39 | while ((bytes = stdin.Read(buffer, 0, buffer.Length)) > 0) { 40 | stdout.Write(buffer, 0, bytes); 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch (web)", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "build", 9 | "program": "${workspaceRoot}/src/IlViewer.WebApi/bin/Debug/netcoreapp1.0/IlViewer.WebApi.dll", 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "stopAtEntry": false, 13 | "internalConsoleOptions": "openOnSessionStart", 14 | "launchBrowser": { 15 | "enabled": true, 16 | "args": "${auto-detect-url}", 17 | "windows": { 18 | "command": "cmd.exe", 19 | "args": "/C start ${auto-detect-url}" 20 | }, 21 | "osx": { 22 | "command": "open" 23 | }, 24 | "linux": { 25 | "command": "xdg-open" 26 | } 27 | }, 28 | "env": { 29 | "ASPNETCORE_ENVIRONMENT": "Development", 30 | "ASPNETCORE_path": "test" 31 | }, 32 | "sourceFileMap": { 33 | "/Views": "${workspaceRoot}/Views" 34 | } 35 | }, 36 | { 37 | "name": ".NET Core Attach", 38 | "type": "coreclr", 39 | "request": "attach", 40 | "processId": "${command.pickProcess}" 41 | } 42 | ] 43 | } -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Controllers/IlViewerController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNetCore.Mvc; 3 | using IlViewer.Core; 4 | using IlViewer.Core.ResultOutput; 5 | using IlViewer.WebApi.Models; 6 | using Microsoft.Extensions.Logging; 7 | 8 | namespace IlViewer.WebApi.Controllers 9 | { 10 | [Route("api/il")] 11 | public class IlViewerController : Controller 12 | { 13 | private readonly LoggerFactory _loggerFactory; 14 | private ILogger _logger; 15 | 16 | [HttpPost] 17 | public InspectionResult Post([FromBody] IlRequest request) 18 | { 19 | if (request == null) 20 | throw new ArgumentNullException(nameof(request)); 21 | 22 | /*_logger = _loggerFactory.CreateLogger();*/ 23 | Console.WriteLine($"Request Params: ProjectFilePath {request.ProjectFilePath}"); 24 | Console.WriteLine($"Request Params: Filename: {request.Filename}"); 25 | /*using (_logger.BeginScope("Request received")) 26 | { 27 | _logger.LogInformation("ProjectFilePath: " + request.ProjectFilePath); 28 | _logger.LogInformation("Filename: " + request.Filename); 29 | }*/ 30 | 31 | try 32 | { 33 | InspectionResult result = IlGeneration.ExtractIl(request.ProjectFilePath, request.Filename); 34 | return result; 35 | } 36 | catch (Exception e) 37 | { 38 | Console.WriteLine(e); 39 | throw; 40 | } 41 | } 42 | 43 | [HttpGet] 44 | public string Ping() 45 | { 46 | return "pong"; 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Visual Studio Code C# IL (Intermediate Language) Viewer 2 | 3 | IL (Intermediate Language) Viewer for Visual Studio Code allows you to rapidly inspect the IL output of any given C# file. 4 | 5 | **Downloading IL Viewer for Visual Studio Code** 6 | [Download C# IL Viewer for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=josephwoodward.vscodeilviewer) or install it directly within Visual Studio Code by launching Quick Open (`CMD + P` for Mac or `CTRL + P` for Windows) and pasting in the follow command and press enter. 7 | 8 | `ext install vscodeilviewer` 9 | 10 | **How does it work?** 11 | Using the power of Roslyn, IL Viewer compiles your chosen file in memory (along with any dependencies it has) and produces an in memory DLL containing the IL. 12 | 13 | ## Features 14 | 15 | **Easy IL Inspection:** 16 | Simply open a .cs file which you'd like to inspect, right-click and select `Inspect IL`. 17 | 18 | ![Easy IL inspection](./images/demo.gif) 19 | 20 | More features coming soon. 21 | 22 | 23 | ## Requirements 24 | 25 | Currently only works on .NET Core apps using project.json. Support for .csproj is coming very soon. 26 | 27 | ## Reporting Issues 28 | 29 | As this is an early version there will likely be issues. Please feel free to raise any issues you run into in the [issues section](https://github.com/JosephWoodward/VSCodeILViewer/issues). 30 | 31 | ## Contributions 32 | 33 | I would love contributions on IL Viewer and welcome contributions of all shapes and sizes. If you're interested in contributing then please feel free to let me know if you need any help getting started. 34 | -------------------------------------------------------------------------------- /src/IlViewer.WebApi/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.NETCore.App": { 4 | "version": "1.0.0", 5 | "type": "platform" 6 | }, 7 | "IlViewer.Core": { 8 | "target":"project" 9 | }, 10 | "Microsoft.AspNetCore.Mvc": "1.0.0", 11 | "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", 12 | "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", 13 | "Microsoft.Extensions.Configuration.FileExtensions": "1.0.0", 14 | "Microsoft.Extensions.Configuration.Json": "1.0.0", 15 | "Microsoft.Extensions.Configuration.CommandLine": "1.0.0", 16 | "Microsoft.Extensions.Logging": "1.0.0", 17 | "Microsoft.Extensions.Logging.Console": "1.0.0", 18 | "Microsoft.Extensions.Logging.Debug": "1.0.0", 19 | "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", 20 | "Serilog": "2.3.0", 21 | "Serilog.Sinks.Literate": "2.0.0", 22 | "Serilog.Sinks.File": "3.2.0", 23 | "Serilog.Extensions.Logging": "1.3.1" 24 | }, 25 | 26 | "frameworks": { 27 | "netcoreapp1.0": { 28 | "imports": [ 29 | "dotnet5.6", 30 | "portable-net45+win8" 31 | ] 32 | } 33 | }, 34 | 35 | "buildOptions": { 36 | "emitEntryPoint": true, 37 | "preserveCompilationContext": true, 38 | "outputName": "ilViewer.WebApi" 39 | }, 40 | 41 | "runtimeOptions": { 42 | "configProperties": { 43 | "System.GC.Server": true 44 | } 45 | }, 46 | 47 | "publishOptions": { 48 | "include": [ 49 | "wwwroot", 50 | "Views", 51 | "Areas/**/Views", 52 | "appsettings.json", 53 | "web.config" 54 | ] 55 | }, 56 | 57 | "tooling": { 58 | "defaultNamespace": "IlViewer.WebApi" 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/IlViewer.WebApi/IlViewer.WebApi.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.0.0 5 | MinimumVisualStudioVersion = 10.0.0.1 6 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "IlViewer.WebApi", "IlViewer.WebApi.xproj", "{A10630E4-1C3C-473B-A64A-6776FF68A1D1}" 7 | EndProject 8 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "IlViewer.Core", "..\IlViewer.Core\IlViewer.Core.xproj", "{0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0}" 9 | EndProject 10 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "IlViewer", "..\IlViewer\IlViewer.xproj", "{344099AB-5007-45B9-8CBA-731FBA166C21}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {A10630E4-1C3C-473B-A64A-6776FF68A1D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {A10630E4-1C3C-473B-A64A-6776FF68A1D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {A10630E4-1C3C-473B-A64A-6776FF68A1D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {A10630E4-1C3C-473B-A64A-6776FF68A1D1}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {0E505AE8-9C6D-4BFC-878E-9B3B3F4B05B0}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {344099AB-5007-45B9-8CBA-731FBA166C21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {344099AB-5007-45B9-8CBA-731FBA166C21}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {344099AB-5007-45B9-8CBA-731FBA166C21}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {344099AB-5007-45B9-8CBA-731FBA166C21}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /src/IlViewer.WebApi/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | using Microsoft.Extensions.Logging; 6 | using Serilog; 7 | using Serilog.Events; 8 | using ILogger = Serilog.ILogger; 9 | 10 | namespace IlViewer.WebApi 11 | { 12 | public class Startup 13 | { 14 | private ILogger Logger { get; } 15 | 16 | public Startup(IHostingEnvironment env) 17 | { 18 | var builder = new ConfigurationBuilder() 19 | .SetBasePath(env.ContentRootPath); 20 | /*.AddCommandLine(Environment.GetCommandLineArgs().Skip(1).ToArray());*/ 21 | 22 | Configuration = builder.Build(); 23 | Logger = new LoggerConfiguration() 24 | .MinimumLevel.Is(LogEventLevel.Debug) 25 | .Enrich.FromLogContext() 26 | .WriteTo.LiterateConsole() 27 | /*.WriteTo.File("", shared: true)*/ 28 | .CreateLogger(); 29 | } 30 | 31 | public IConfigurationRoot Configuration { get; } 32 | 33 | // This method gets called by the runtime. Use this method to add services to the container. 34 | public void ConfigureServices(IServiceCollection services) 35 | { 36 | /*Console.WriteLine("Port: " + Configuration.GetSection("server:port")); 37 | Console.WriteLine("Port2: " + Configuration["server:urls"]); 38 | Console.WriteLine("Port3: " + Configuration["server__urls"]); 39 | Console.WriteLine("Port3: " + Configuration["server.urls"]);*/ 40 | // Add framework services. 41 | services.AddMvc(); 42 | } 43 | 44 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 45 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 46 | { 47 | /*loggerFactory.AddSerilog(Logger); 48 | loggerFactory.AddDebug();*/ 49 | 50 | app.UseMvc(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/vscodeilviewer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vscodeilviewer", 3 | "displayName": "C# IL Viewer", 4 | "description": "A C# IL Viewer for Visual Studio Code", 5 | "version": "0.0.1", 6 | "author": "Joseph Woodward", 7 | "license": "See licence in license file", 8 | "publisher": "josephwoodward", 9 | "engines": { 10 | "vscode": "^1.5.0" 11 | }, 12 | "icon": "logo.png", 13 | "galleryBanner": { 14 | "color": "#595959", 15 | "theme": "dark" 16 | }, 17 | "bugs": { 18 | "url": "https://github.com/JosephWoodward/VSCodeILViewer/issues", 19 | "email": "joseph.woodward@xeuse.com" 20 | }, 21 | "categories": [ 22 | "Languages", 23 | "Other" 24 | ], 25 | "repository": { 26 | "type": "git", 27 | "url": "https://github.com/JosephWoodward/VSCodeILViewer.git" 28 | }, 29 | "homepage": "https://github.com/JosephWoodward/VSCodeILViewer/blob/master/README.md", 30 | "activationEvents": [ 31 | "onCommand:extension.showIlWindow", 32 | "onLanguage:csharp", 33 | "workspaceContains:project.json" 34 | ], 35 | "main": "./out/src/extension", 36 | "contributes": { 37 | "commands": [{ 38 | "command": "extension.showIlWindow", 39 | "title": "Inspect IL" 40 | }], 41 | "menus": { 42 | "editor/context": [{ 43 | "command": "extension.showIlWindow", 44 | "when": "editorTextFocus && editorLangId == csharp", 45 | "group": "navigation@1.31" 46 | }] 47 | } 48 | }, 49 | "scripts": { 50 | "vscode:prepublish": "tsc -p ./", 51 | "compile": "tsc -watch -p ./", 52 | "postinstall": "node ./node_modules/vscode/bin/install", 53 | "test": "node ./node_modules/vscode/bin/test" 54 | }, 55 | "devDependencies": { 56 | "typescript": "^2.0.3", 57 | "vscode": "^1.0.0", 58 | "mocha": "^2.3.3", 59 | "@types/node": "^6.0.40", 60 | "@types/mocha": "^2.2.32" 61 | }, 62 | "dependencies": { 63 | "request": "2.79.0", 64 | "find-parent-dir": "0.3.0" 65 | } 66 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your first VS Code Extension 2 | 3 | ## What's in the folder 4 | * This folder contains all of the files necessary for your extension 5 | * `package.json` - this is the manifest file in which you declare your extension and command. 6 | The sample plugin registers a command and defines its title and command name. With this information 7 | VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `src/extension.ts` - this is the main file where you will provide the implementation of your command. 9 | The file exports one function, `activate`, which is called the very first time your extension is 10 | activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 11 | We pass the function containing the implementation of the command as the second parameter to 12 | `registerCommand`. 13 | 14 | ## Get up and running straight away 15 | * press `F5` to open a new window with your extension loaded 16 | * run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World` 17 | * set breakpoints in your code inside `src/extension.ts` to debug your extension 18 | * find output from your extension in the debug console 19 | 20 | ## Make changes 21 | * you can relaunch the extension from the debug toolbar after changing code in `src/extension.ts` 22 | * you can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes 23 | 24 | ## Explore the API 25 | * you can open the full set of our API when you open the file `node_modules/vscode/vscode.d.ts` 26 | 27 | ## Run tests 28 | * open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Launch Tests` 29 | * press `F5` to run the tests in a new window with your extension loaded 30 | * see the output of the test result in the debug console 31 | * make changes to `test/extension.test.ts` or create new test files inside the `test` folder 32 | * by convention, the test runner will only consider files matching the name pattern `**.test.ts` 33 | * you can create folders inside the `test` folder to structure your tests any way you want -------------------------------------------------------------------------------- /src/IlViewer.Core/RoslynClass.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Mono.Cecil; 4 | using Mono.Cecil.Cil; 5 | using Mono.Collections.Generic; 6 | 7 | namespace IlViewer.Core 8 | { 9 | public class RoslynClass 10 | { 11 | public static Dictionary> GetiLInstructionsFromAssembly(AssemblyDefinition assembly, string typeName) 12 | { 13 | var ilInstructions = new Dictionary>(); 14 | var typeDefinitions = assembly.MainModule.GetTypes().ToList(); 15 | 16 | TypeDefinition typeDefinition = typeDefinitions.FirstOrDefault(x => x.Name == typeName) ?? typeDefinitions.FirstOrDefault(x => x.Name.Contains(typeName) && x.HasGenericParameters); 17 | if (typeDefinition != null) 18 | { 19 | foreach (var method in typeDefinition.Methods) 20 | { 21 | ilInstructions.Add(method.FullName, method.Body?.Instructions ?? new Collection()); 22 | } 23 | 24 | foreach (var nestedType in typeDefinition.NestedTypes) 25 | { 26 | foreach (var method in nestedType.Methods) 27 | { 28 | ilInstructions.Add(method.FullName, method.Body?.Instructions ?? new Collection()); 29 | } 30 | 31 | foreach (var nestedNestedType in nestedType.NestedTypes) 32 | { 33 | foreach (var method in nestedNestedType.Methods) 34 | { 35 | ilInstructions.Add(method.FullName, method.Body?.Instructions ?? new Collection()); 36 | } 37 | } 38 | } 39 | } 40 | else 41 | { 42 | ModuleDefinition module = assembly.MainModule; 43 | 44 | var ilProcessor = module?.EntryPoint?.Body?.GetILProcessor(); 45 | if (ilProcessor != null) 46 | { 47 | ilInstructions.Add(assembly.MainModule.EntryPoint.FullName, ilProcessor?.Body?.Instructions ?? new Collection()); 48 | } 49 | } 50 | 51 | return ilInstructions; 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/CSharpLanguage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Microsoft.CodeAnalysis; 6 | using Microsoft.CodeAnalysis.CSharp; 7 | using Microsoft.CSharp.RuntimeBinder; 8 | 9 | namespace IlViewer.Core 10 | { 11 | public class CSharpLanguage 12 | { 13 | private static readonly LanguageVersion MaxLanguageVersion = Enum 14 | .GetValues(typeof (LanguageVersion)) 15 | .Cast() 16 | .Max(); 17 | private static readonly IReadOnlyCollection PreprocessorSymbols = new[] { "__DEMO_EXPERIMENTAL__" }; 18 | 19 | // ReSharper disable once AgentHeisenbug.FieldOfNonThreadSafeTypeInThreadSafeType 20 | private readonly IReadOnlyCollection _references = new[] { 21 | MetadataReference.CreateFromFile(typeof(Binder).GetTypeInfo().Assembly.Location), 22 | MetadataReference.CreateFromFile(typeof(ValueTuple<>).GetTypeInfo().Assembly.Location) 23 | }; 24 | 25 | 26 | private readonly IReadOnlyDictionary _features; 27 | 28 | public CSharpLanguage() 29 | { 30 | 31 | } 32 | // public CSharpLanguage(IFeatureDiscovery featureDiscovery) { 33 | // _features = featureDiscovery.SlowDiscoverAll().ToDictionary(f => f, f => (string)null); 34 | // } 35 | 36 | // public LanguageIdentifier Identifier => LanguageIdentifier.CSharp; 37 | 38 | public SyntaxTree ParseText(string code, SourceCodeKind kind) { 39 | var options = new CSharpParseOptions( 40 | kind: kind, 41 | languageVersion: MaxLanguageVersion, 42 | preprocessorSymbols: PreprocessorSymbols 43 | ); 44 | return CSharpSyntaxTree.ParseText(code, options); 45 | } 46 | 47 | public Compilation CreateLibraryCompilation(string assemblyName, bool optimizationsEnabled) { 48 | var options = new CSharpCompilationOptions( 49 | OutputKind.DynamicallyLinkedLibrary, 50 | optimizationLevel: optimizationsEnabled ? OptimizationLevel.Release : OptimizationLevel.Debug, 51 | allowUnsafe: true 52 | ); 53 | 54 | return CSharpCompilation.Create(assemblyName, options: options, references: _references); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/ProjectContextLens.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.DotNet.ProjectModel; 4 | using Microsoft.DotNet.ProjectModel.Compilation; 5 | using Microsoft.DotNet.ProjectModel.Graph; 6 | using Microsoft.DotNet.ProjectModel.Resolution; 7 | 8 | namespace IlViewer.Core 9 | { 10 | public class ProjectContextLens 11 | { 12 | private readonly string _configuration; 13 | private readonly ProjectContext _context; 14 | private readonly List _sourceFiles = new List(); 15 | private readonly List _fileReferences = new List(); 16 | private readonly List _projectReferenes = new List(); 17 | 18 | public ProjectContextLens(ProjectContext context, string configuration) 19 | { 20 | _context = context; 21 | _configuration = configuration; 22 | Resolve(); 23 | } 24 | 25 | public IEnumerable SourceFiles => _sourceFiles; 26 | 27 | public IEnumerable FileReferences => _fileReferences; 28 | 29 | public IEnumerable ProjectReferences => _projectReferenes; 30 | 31 | private void Resolve() 32 | { 33 | _sourceFiles.AddRange(_context.ProjectFile.Files.SourceFiles); 34 | var exporter = _context.CreateExporter(_configuration); 35 | 36 | var library = exporter.LibraryManager; 37 | ResolveLibraries(library); 38 | 39 | foreach (var export in exporter.GetAllExports()) 40 | { 41 | 42 | ResolveFileReferences(export); 43 | ResolveProjectReference(export); 44 | ResolveSourceFiles(export); 45 | } 46 | } 47 | 48 | private void ResolveLibraries(LibraryManager libraryManager) 49 | { 50 | var allDiagnostics = libraryManager.GetAllDiagnostics(); 51 | var unresolved = libraryManager.GetLibraries().Where(dep => !dep.Resolved); 52 | var needRestore = allDiagnostics.Any(diag => diag.ErrorCode == ErrorCodes.NU1006) || unresolved.Any(); 53 | } 54 | 55 | private void ResolveSourceFiles(LibraryExport export) 56 | { 57 | foreach (var file in export.SourceReferences) 58 | { 59 | _sourceFiles.Add(file.ResolvedPath); 60 | } 61 | } 62 | 63 | private void ResolveFileReferences(LibraryExport export) 64 | { 65 | if (export.Library.Identity.Type != LibraryType.Project) 66 | { 67 | _fileReferences.AddRange(export.CompilationAssemblies.Select(asset => asset.ResolvedPath)); 68 | } 69 | } 70 | 71 | private void ResolveProjectReference(LibraryExport export) 72 | { 73 | var desc = export.Library as ProjectDescription; 74 | if (desc == null || export.Library.Identity.Type != LibraryType.Project) 75 | { 76 | return; 77 | } 78 | 79 | if (export.Library.Identity.Name == _context.ProjectFile.Name) 80 | { 81 | return; 82 | } 83 | 84 | if (!string.IsNullOrEmpty(desc?.TargetFrameworkInfo?.AssemblyPath)) 85 | { 86 | return; 87 | } 88 | 89 | _sourceFiles.AddRange(export.SourceReferences.Select(source => source.ResolvedPath)); 90 | _projectReferenes.Add(desc); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /src/vscodeilviewer/src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { IntermediateLanguageContentProvider } from './IntermediateLanguageContentProvider'; 4 | import { DecompilerProcess } from './process'; 5 | import { Logger } from './logger'; 6 | import * as path from 'path'; 7 | import * as vscode from 'vscode'; 8 | import * as child_process from 'child_process'; 9 | import * as fs from 'fs'; 10 | import * as os from 'os'; 11 | 12 | let child : child_process.ChildProcess; 13 | let ilWindowUri = vscode.Uri.parse(`il-viewer://authority/${IntermediateLanguageContentProvider.Scheme}`); 14 | let logger = new Logger(message => console.log(message), "Info"); 15 | 16 | const disposables: vscode.Disposable[] = []; 17 | 18 | export function activate(context: vscode.ExtensionContext) { 19 | logger.append("Executing activate"); 20 | 21 | let invokationDisposable = vscode.commands.registerCommand('extension.showIlWindow', () => { 22 | return vscode.commands.executeCommand('vscode.previewHtml', ilWindowUri, vscode.ViewColumn.Two, 'IL Viewer').then((success) => { 23 | }, (reason) => { 24 | vscode.window.showErrorMessage("There's been an error: " + reason); 25 | }); 26 | }); 27 | disposables.push(invokationDisposable); 28 | 29 | let provider = new IntermediateLanguageContentProvider(ilWindowUri); 30 | let providerDisposable = vscode.workspace.registerTextDocumentContentProvider(IntermediateLanguageContentProvider.Scheme, provider); 31 | disposables.push(providerDisposable); 32 | 33 | const fullPath = path.join(vscode.extensions.getExtension("josephwoodward.vscodeilviewer").extensionPath) + "/server/ilViewer.WebApi.dll"; 34 | fs.exists(fullPath, function(exists){ 35 | if (!exists){ 36 | logger.appendLine(`Unable to start server, can't find path at ${fullPath}`); 37 | vscode.window.showErrorMessage("Unable to start IL Viewer server, check developer console"); 38 | return; 39 | } 40 | 41 | //startServer(fullPath); 42 | }); 43 | 44 | context.subscriptions.push(...disposables); 45 | } 46 | 47 | export function deactivate() { 48 | child.kill('SIGTERM'); 49 | } 50 | 51 | export function startServer(path: string){ 52 | 53 | child = DecompilerProcess.spawn(path, [ ], logger); 54 | child.on('error', data => { 55 | logger.appendLine("Error starting server"); 56 | console.log(`Child error`); 57 | }); 58 | 59 | let out = child.stdout; 60 | out.on("readable", function(){ 61 | let data = child.stdout.read(); 62 | }); 63 | 64 | process.on('SIGTERM', () => { 65 | child.kill(); 66 | process.exit(0); 67 | }); 68 | 69 | process.on('SIGHUP', () => { 70 | child.kill(); 71 | process.exit(0); 72 | }); 73 | 74 | child.on('close', code => { 75 | // if (code !== 0) { 76 | // var data = code.toString(); 77 | // } else { 78 | // var data = code.toString(); 79 | // } 80 | // let data = (code != null) ? code.toString() : "unknown"; 81 | logger.appendLine("Closing server"); 82 | }); 83 | 84 | child.stdout.on('data', data => { 85 | let response = data != null ? data.toString() : ""; 86 | logger.appendLine(`Server output: ${response}`) 87 | process.stdout.write(data); 88 | }); 89 | 90 | process.stdin.on('data', data => { 91 | var res = data.toString(); 92 | child.stdin.write(data); 93 | }); 94 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | .vs 9 | .idea 10 | project.lock.json 11 | docker-compose.prod.yml 12 | docker-compose.dev.yml 13 | 14 | # Build results 15 | 16 | [Dd]ebug/ 17 | [Rr]elease/ 18 | x64/ 19 | build/ 20 | [Bb]in/ 21 | [Oo]bj/ 22 | #dist/ 23 | 24 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 25 | !packages/*/build/ 26 | 27 | # MSTest test Results 28 | [Tt]est[Rr]esult*/ 29 | [Bb]uild[Ll]og.* 30 | 31 | *_i.c 32 | *_p.c 33 | *.ilk 34 | *.meta 35 | *.obj 36 | *.pch 37 | *.pdb 38 | *.pgc 39 | *.pgd 40 | *.rsp 41 | *.sbr 42 | *.tlb 43 | *.tli 44 | *.tlh 45 | *.tmp 46 | *.tmp_proj 47 | *.log 48 | *.vspscc 49 | *.vssscc 50 | .builds 51 | *.pidb 52 | *.log 53 | *.scc 54 | 55 | # Visual C++ cache files 56 | ipch/ 57 | *.aps 58 | *.ncb 59 | *.opensdf 60 | *.sdf 61 | *.cachefile 62 | 63 | # Visual Studio profiler 64 | *.psess 65 | *.vsp 66 | *.vspx 67 | 68 | # Guidance Automation Toolkit 69 | *.gpState 70 | 71 | # ReSharper is a .NET coding add-in 72 | _ReSharper*/ 73 | *.[Rr]e[Ss]harper 74 | 75 | # TeamCity is a build add-in 76 | _TeamCity* 77 | 78 | # DotCover is a Code Coverage Tool 79 | *.dotCover 80 | 81 | # NCrunch 82 | *.ncrunch* 83 | .*crunch*.local.xml 84 | 85 | # Installshield output folder 86 | [Ee]xpress/ 87 | 88 | # DocProject is a documentation generator add-in 89 | DocProject/buildhelp/ 90 | DocProject/Help/*.HxT 91 | DocProject/Help/*.HxC 92 | DocProject/Help/*.hhc 93 | DocProject/Help/*.hhk 94 | DocProject/Help/*.hhp 95 | DocProject/Help/Html2 96 | DocProject/Help/html 97 | 98 | # Click-Once directory 99 | publish/ 100 | 101 | # Publish Web Output 102 | *.Publish.xml 103 | 104 | # NuGet Packages Directory 105 | packages/ 106 | !packages/repositories.config 107 | 108 | # Windows Azure Build Output 109 | csx 110 | *.build.csdef 111 | 112 | # Windows Store app package directory 113 | AppPackages/ 114 | 115 | # Others 116 | sql/ 117 | *.Cache 118 | ClientBin/ 119 | [Ss]tyle[Cc]op.* 120 | ~$* 121 | *~ 122 | *.dbmdl 123 | *.[Pp]ublish.xml 124 | *.pfx 125 | *.publishsettings 126 | node_modules/ 127 | bower_components/ 128 | tmp/ 129 | 130 | # RIA/Silverlight projects 131 | Generated_Code/ 132 | 133 | # Backup & report files from converting an old project file to a newer 134 | # Visual Studio version. Backup files are not needed, because we have git ;-) 135 | _UpgradeReport_Files/ 136 | Backup*/ 137 | UpgradeLog*.XML 138 | UpgradeLog*.htm 139 | 140 | # SQL Server files 141 | App_Data/*.mdf 142 | App_Data/*.ldf 143 | 144 | 145 | #LightSwitch generated files 146 | GeneratedArtifacts/ 147 | _Pvt_Extensions/ 148 | ModelManifest.xml 149 | 150 | # ========================= 151 | # Windows detritus 152 | # ========================= 153 | 154 | # Windows image file caches 155 | Thumbs.db 156 | ehthumbs.db 157 | 158 | # Folder config file 159 | Desktop.ini 160 | 161 | # Recycle Bin used on file shares 162 | $RECYCLE.BIN/ 163 | 164 | # Mac desktop service store files 165 | .DS_Store 166 | 167 | bower_components/ 168 | node_modules/ 169 | **/wwwroot/lib/ 170 | **/wwwroot/img/media/ 171 | .settings 172 | **/PublishProfiles/ 173 | **/PublishScripts/ 174 | 175 | # Angular 2 176 | # compiled output 177 | AdminApp/dist 178 | AdminApp/tmp 179 | 180 | # dependencies 181 | AdminApp/node_modules 182 | AdminApp/bower_components 183 | 184 | # IDEs and editors 185 | AdminApp/.idea 186 | 187 | # misc 188 | AdminApp/.sass-cache 189 | AdminApp/connect.lock 190 | AdminApp/coverage/* 191 | AdminApp/libpeerconnection.log 192 | AdminApp/AdminApp/npm-debug.log 193 | AdminApp/testem.log 194 | AdminApp/typings 195 | 196 | # e2e 197 | AdminApp/e2e/*.js 198 | AdminApp/e2e/*.map 199 | 200 | #System Files 201 | .DS_Store 202 | Thumbs.db -------------------------------------------------------------------------------- /src/vscodeilviewer/src/IntermediateLanguageContentProvider.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import * as vscode from 'vscode'; 3 | import * as os from 'os'; 4 | import * as request from 'request'; 5 | import * as findParentDir from 'find-parent-dir'; 6 | 7 | let parsePath = () => { 8 | let document = vscode.window.activeTextEditor.document; 9 | let parsedPath = path.parse(document.fileName); 10 | return parsedPath; 11 | } 12 | 13 | export class IntermediateLanguageContentProvider implements vscode.TextDocumentContentProvider { 14 | 15 | public static Scheme = 'il-viewer'; 16 | 17 | private _response; 18 | private _previewUri; 19 | private _onDidChange = new vscode.EventEmitter(); 20 | 21 | constructor(previewUri : vscode.Uri,) { 22 | this._previewUri = previewUri; 23 | } 24 | 25 | // Implementation 26 | public provideTextDocumentContent(uri: vscode.Uri) : string { 27 | 28 | if (!this._response){ 29 | this.findProjectJson((projectJson, filename) => { 30 | return this.requstIl(projectJson, filename); 31 | }) 32 | 33 | return ` 34 |

Inspecting IL, hold onto your seat belts!

35 |

If this is your first inspection then it may take a moment longer.

`; 36 | } 37 | 38 | let output = this.renderPage(this._response); 39 | this._response = null; 40 | 41 | return output; 42 | } 43 | 44 | get onDidChange(): vscode.Event { 45 | return this._onDidChange.event; 46 | } 47 | 48 | private findProjectJson(requestIntermediateLanguage){ 49 | const parsedPath = parsePath(); 50 | const filename = parsedPath.name; 51 | 52 | findParentDir(parsedPath.dir, 'project.json', function (err, dir) { 53 | if (dir !== null){ 54 | requestIntermediateLanguage(parsedPath.name, dir); 55 | return; 56 | } 57 | }) 58 | } 59 | 60 | private renderPage(body: IInspectionResult) : string { 61 | let output = ""; 62 | if (body.hasErrors && body.compilationErrors.length > 0) { 63 | output += "

Unable to extract IL for the following reason(s):

"; 64 | output += "
    "; 65 | body.compilationErrors.forEach(function(value : ICompilationError, index: number){ 66 | output += "
  1. " + value.message + "
  2. "; 67 | }); 68 | output += "
"; 69 | } else if (body.ilResults.length > 0) { 70 | body.ilResults.forEach(function(value: IInstructionResult, index: number){ 71 | output += "
" + value.value + "
"; 72 | }); 73 | } 74 | 75 | return ` 76 | 86 | 87 | ${output} 88 | `; 89 | } 90 | 91 | public requstIl(filename: string, projectJsonPath : string) { 92 | 93 | let postData = { 94 | ProjectFilePath : projectJsonPath, 95 | Filename : filename 96 | } 97 | 98 | let options = { 99 | method: 'post', 100 | body: postData, 101 | json: true, 102 | url: 'http://localhost:65530/api/il/' 103 | } 104 | 105 | request(options, (error, response, body) => { 106 | if (!error && response.statusCode == 200) { 107 | this._response = body; 108 | this._onDidChange.fire(this._previewUri); 109 | } else if (!error && response.statusCode == 500) { 110 | // Something went wrong! 111 | this._response = ` 112 |

Uh oh, something went wrong.

113 |

${body}

`; 114 | this._onDidChange.fire(this._previewUri); 115 | } 116 | }); 117 | } 118 | } -------------------------------------------------------------------------------- /src/IlViewer.Core/IlGeneration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using IlViewer.Core.ResultOutput; 6 | using Microsoft.CodeAnalysis; 7 | using Microsoft.Extensions.Logging; 8 | using Mono.Cecil; 9 | using Mono.Cecil.Cil; 10 | using Mono.Collections.Generic; 11 | 12 | namespace IlViewer.Core 13 | { 14 | public static class IlGeneration 15 | { 16 | public static InspectionResult ExtractIl(string projectJsonPath, string classFilename) 17 | { 18 | if (string.IsNullOrEmpty(projectJsonPath)) 19 | throw new ArgumentNullException(nameof(projectJsonPath)); 20 | 21 | if (string.IsNullOrEmpty(classFilename)) 22 | throw new ArgumentNullException(nameof(classFilename)); 23 | 24 | Compilation workspaceCompilation = WorkspaceManager.LoadWorkspace(projectJsonPath); 25 | 26 | var inspectionResult = new InspectionResult(); 27 | using (var stream = new MemoryStream()) 28 | { 29 | var compilationResult = workspaceCompilation.Emit(stream); 30 | if (!compilationResult.Success) 31 | { 32 | var errors = compilationResult.Diagnostics.Where(x => x.Severity == DiagnosticSeverity.Error).ToList(); 33 | foreach (var error in errors) 34 | { 35 | inspectionResult.AddError(error.GetMessage()); 36 | Console.WriteLine(error.ToString()); 37 | } 38 | 39 | if (inspectionResult.HasErrors) 40 | return inspectionResult; 41 | } 42 | 43 | stream.Seek(0, SeekOrigin.Begin); 44 | 45 | //AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(stream); 46 | PortableExecutableReference ref2 = MetadataReference.CreateFromStream(stream); 47 | 48 | var syntaxTree2 = workspaceCompilation.SyntaxTrees.Where(x => x.FilePath.Contains(classFilename)); 49 | var trees = workspaceCompilation.SyntaxTrees.ToList(); 50 | 51 | var allTrees = trees.Where(x => x.FilePath.Contains(classFilename + ".cs")).ToList(); 52 | //TODO: optimise this 53 | 54 | var syntaxTree = allTrees.FirstOrDefault(x => x.FilePath.Contains("\\" + classFilename + ".cs")); 55 | if (syntaxTree == null) 56 | syntaxTree = allTrees.FirstOrDefault(x => x.FilePath.Contains("/" + classFilename + ".cs")); 57 | 58 | var sourceCode = syntaxTree.GetText().ToString(); 59 | 60 | var metadataReferences = workspaceCompilation.References.ToList(); 61 | var res3 = ref2.GetMetadata(); 62 | metadataReferences.Add(ref2); 63 | 64 | InspectionResult finalResult = CompileInMemory(sourceCode, metadataReferences, classFilename, inspectionResult); 65 | return finalResult; 66 | } 67 | } 68 | 69 | private static InspectionResult CompileInMemory(string sourceCode, IEnumerable metadataReferences, string classFilename, InspectionResult inspectionResult) 70 | { 71 | var sourceLanguage = new CSharpLanguage(); 72 | var syntaxTree = sourceLanguage.ParseText(sourceCode, SourceCodeKind.Regular); 73 | 74 | var stream = new MemoryStream(); 75 | Compilation compilation = sourceLanguage 76 | .CreateLibraryCompilation("ExampleAssembly", false) 77 | .AddReferences(metadataReferences) 78 | .AddReferences() 79 | .AddSyntaxTrees(syntaxTree); 80 | 81 | var emitResult = compilation.Emit(stream); 82 | if (!emitResult.Success) 83 | { 84 | var errors = emitResult.Diagnostics.Where(x => x.Severity == DiagnosticSeverity.Error); 85 | foreach (var error in errors) 86 | { 87 | inspectionResult.AddError(error.GetMessage()); 88 | Console.WriteLine(error.ToString()); 89 | } 90 | 91 | if (inspectionResult.HasErrors) 92 | return inspectionResult; 93 | } 94 | 95 | stream.Seek(0, SeekOrigin.Begin); 96 | 97 | //var resultWriter = new StringWriter(); 98 | //var decompiler = new ILDecompiler(); 99 | //decompiler.Decompile(stream, resultWriter); 100 | 101 | var ilResult = GenerateIlFromStream(stream, classFilename); 102 | inspectionResult.IlResults = ilResult; 103 | 104 | return inspectionResult; 105 | } 106 | 107 | private static IList GenerateIlFromStream(Stream stream, string typeFullName) 108 | { 109 | var assembly = AssemblyDefinition.ReadAssembly(stream); 110 | 111 | Dictionary> result; 112 | try 113 | { 114 | result = RoslynClass.GetiLInstructionsFromAssembly(assembly, typeFullName); 115 | } 116 | catch (Exception e) 117 | { 118 | Console.WriteLine(e); 119 | throw; 120 | } 121 | 122 | 123 | var output = new List(); 124 | foreach(var item in result) 125 | { 126 | output.Add(new InstructionResult {Value = item.Key}); 127 | foreach(var i in item.Value) 128 | { 129 | Console.WriteLine(i.ToString()); 130 | output.Add(new InstructionResult { 131 | // IlOpCode = i.OpCode.ToString(), 132 | // IlOperand = i.Operand.ToString(), 133 | Value = i.ToString() 134 | }); 135 | } 136 | } 137 | 138 | return output; 139 | } 140 | } 141 | } --------------------------------------------------------------------------------