Skip to content

Commit 5412edb

Browse files
devhawkHarry
andauthored
* include project folder path in debug info (#770)
* relative path for debug info documents * Only include documents that actually have associated sequence points Co-authored-by: Harry <harrypierson@ngd.neo.org>
1 parent fa29c6d commit 5412edb

2 files changed

Lines changed: 57 additions & 39 deletions

File tree

src/Neo.Compiler.CSharp/CompilationContext.cs

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (C) 2015-2022 The Neo Project.
2-
//
3-
// The Neo.Compiler.CSharp is free software distributed under the MIT
4-
// software license, see the accompanying file LICENSE in the main directory
5-
// of the project or http://www.opensource.org/licenses/mit-license.php
2+
//
3+
// The Neo.Compiler.CSharp is free software distributed under the MIT
4+
// software license, see the accompanying file LICENSE in the main directory
5+
// of the project or http://www.opensource.org/licenses/mit-license.php
66
// for more details.
7-
//
7+
//
88
// Redistribution and use in source and binary forms with or without
99
// modifications are permitted.
1010

@@ -13,6 +13,7 @@
1313
using Microsoft.CodeAnalysis;
1414
using Microsoft.CodeAnalysis.CSharp;
1515
using Microsoft.CodeAnalysis.CSharp.Syntax;
16+
using Microsoft.CodeAnalysis.Text;
1617
using Neo.Cryptography.ECC;
1718
using Neo.Json;
1819
using Neo.SmartContract;
@@ -327,15 +328,36 @@ public JObject CreateManifest()
327328
};
328329
}
329330

330-
public JObject CreateDebugInformation()
331+
public JObject CreateDebugInformation(string folder = "")
331332
{
332-
string[] sourceLocations = GetSourceLocations(compilation).Distinct().ToArray();
333-
return new JObject
333+
List<string> documents = new();
334+
List<JObject> methods = new();
335+
foreach (var m in methodsConverted.Where(p => p.SyntaxNode is not null))
334336
{
335-
["hash"] = Script.ToScriptHash().ToString(),
336-
["documents"] = sourceLocations.Select(p => (JString)p!).ToArray(),
337-
["static-variables"] = staticFields.OrderBy(p => p.Value).Select(p => ((JString)$"{p.Key.Name},{p.Key.Type.GetContractParameterType()},{p.Value}")!).ToArray(),
338-
["methods"] = methodsConverted.Where(p => p.SyntaxNode is not null).Select(m => new JObject
337+
List<JString> sequencePoints = new();
338+
foreach (var ins in m.Instructions.Where(i => i.SourceLocation is not null))
339+
{
340+
var doc = ins.SourceLocation!.SourceTree!.FilePath;
341+
if (!string.IsNullOrEmpty(folder))
342+
{
343+
doc = Path.GetRelativePath(folder, doc);
344+
}
345+
346+
var index = documents.IndexOf(doc);
347+
if (index == -1)
348+
{
349+
index = documents.Count;
350+
documents.Add(doc);
351+
}
352+
353+
FileLinePositionSpan span = ins.SourceLocation!.GetLineSpan();
354+
var str = $"{ins.Offset}[{index}]{ToRangeString(span.StartLinePosition)}-{ToRangeString(span.EndLinePosition)}";
355+
sequencePoints.Add(new JString(str));
356+
357+
static string ToRangeString(LinePosition pos) => $"{pos.Line + 1}:{pos.Character + 1}";
358+
}
359+
360+
methods.Add(new JObject
339361
{
340362
["id"] = m.Symbol.ToString(),
341363
["name"] = $"{m.Symbol.ContainingType},{m.Symbol.Name}",
@@ -346,12 +368,17 @@ public JObject CreateDebugInformation()
346368
.ToArray(),
347369
["return"] = m.Symbol.ReturnType.GetContractParameterType().ToString(),
348370
["variables"] = m.Variables.Select(p => ((JString)$"{p.Symbol.Name},{p.Symbol.Type.GetContractParameterType()},{p.SlotIndex}")!).ToArray(),
349-
["sequence-points"] = m.Instructions.Where(p => p.SourceLocation is not null).Select(p =>
350-
{
351-
FileLinePositionSpan span = p.SourceLocation!.GetLineSpan();
352-
return ((JString)$"{p.Offset}[{Array.IndexOf(sourceLocations, p.SourceLocation.SourceTree!.FilePath)}]{span.StartLinePosition.Line + 1}:{span.StartLinePosition.Character + 1}-{span.EndLinePosition.Line + 1}:{span.EndLinePosition.Character + 1}")!;
353-
}).ToArray()
354-
}).ToArray(),
371+
["sequence-points"] = sequencePoints.ToArray(),
372+
});
373+
}
374+
375+
return new JObject
376+
{
377+
["hash"] = Script.ToScriptHash().ToString(),
378+
["documents"] = documents.Select(p => (JString)p!).ToArray(),
379+
["document-root"] = string.IsNullOrEmpty(folder) ? JToken.Null : folder,
380+
["static-variables"] = staticFields.OrderBy(p => p.Value).Select(p => ((JString)$"{p.Key.Name},{p.Key.Type.GetContractParameterType()},{p.Value}")!).ToArray(),
381+
["methods"] = methods.ToArray(),
355382
["events"] = eventsExported.Select(e => new JObject
356383
{
357384
["id"] = e.Name,
@@ -361,15 +388,6 @@ public JObject CreateDebugInformation()
361388
};
362389
}
363390

364-
private static IEnumerable<string> GetSourceLocations(Compilation compilation)
365-
{
366-
foreach (SyntaxTree syntaxTree in compilation.SyntaxTrees)
367-
yield return syntaxTree.FilePath;
368-
foreach (CompilationReference reference in compilation.References.OfType<CompilationReference>())
369-
foreach (string path in GetSourceLocations(reference.Compilation))
370-
yield return path;
371-
}
372-
373391
private void ProcessCompilationUnit(HashSet<INamedTypeSymbol> processed, SemanticModel model, CompilationUnitSyntax syntax)
374392
{
375393
foreach (MemberDeclarationSyntax member in syntax.Members)

src/Neo.Compiler.CSharp/Program.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (C) 2015-2022 The Neo Project.
2-
//
3-
// The Neo.Compiler.CSharp is free software distributed under the MIT
4-
// software license, see the accompanying file LICENSE in the main directory
5-
// of the project or http://www.opensource.org/licenses/mit-license.php
2+
//
3+
// The Neo.Compiler.CSharp is free software distributed under the MIT
4+
// software license, see the accompanying file LICENSE in the main directory
5+
// of the project or http://www.opensource.org/licenses/mit-license.php
66
// for more details.
7-
//
7+
//
88
// Redistribution and use in source and binary forms with or without
99
// modifications are permitted.
1010

@@ -127,26 +127,26 @@ private static int ProcessOutputs(Options options, string folder, CompilationCon
127127
if (context.Success)
128128
{
129129
string baseName = options.BaseName ?? context.ContractName!;
130-
folder = options.Output ?? Path.Combine(folder, "bin", "sc");
131-
Directory.CreateDirectory(folder);
132-
string path = Path.Combine(folder, $"{baseName}.nef");
130+
string outputFolder = options.Output ?? Path.Combine(folder, "bin", "sc");
131+
Directory.CreateDirectory(outputFolder);
132+
string path = Path.Combine(outputFolder, $"{baseName}.nef");
133133
File.WriteAllBytes(path, context.CreateExecutable().ToArray());
134134
Console.WriteLine($"Created {path}");
135-
path = Path.Combine(folder, $"{baseName}.manifest.json");
135+
path = Path.Combine(outputFolder, $"{baseName}.manifest.json");
136136
File.WriteAllBytes(path, context.CreateManifest().ToByteArray(false));
137137
Console.WriteLine($"Created {path}");
138138
if (options.Debug)
139139
{
140-
path = Path.Combine(folder, $"{baseName}.nefdbgnfo");
140+
path = Path.Combine(outputFolder, $"{baseName}.nefdbgnfo");
141141
using FileStream fs = new(path, FileMode.Create, FileAccess.Write);
142142
using ZipArchive archive = new(fs, ZipArchiveMode.Create);
143143
using Stream stream = archive.CreateEntry($"{baseName}.debug.json").Open();
144-
stream.Write(context.CreateDebugInformation().ToByteArray(false));
144+
stream.Write(context.CreateDebugInformation(folder).ToByteArray(false));
145145
Console.WriteLine($"Created {path}");
146146
}
147147
if (options.Assembly)
148148
{
149-
path = Path.Combine(folder, $"{baseName}.asm");
149+
path = Path.Combine(outputFolder, $"{baseName}.asm");
150150
File.WriteAllText(path, context.CreateAssembly());
151151
Console.WriteLine($"Created {path}");
152152
}

0 commit comments

Comments
 (0)