();
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 += "- " + value.message + "
";
67 | });
68 | output += "
";
69 | } else if (body.ilResults.length > 0) {
70 | body.ilResults.forEach(function(value: IInstructionResult, index: number){
71 | output += "";
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 | }
--------------------------------------------------------------------------------