Skip to content

Commit

Permalink
* include project folder path in debug info (#770)
Browse files Browse the repository at this point in the history
* relative path for debug info documents
* Only include documents that actually have associated sequence points

Co-authored-by: Harry <[email protected]>
  • Loading branch information
devhawk and Harry committed Nov 20, 2022
1 parent fa29c6d commit 5412edb
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 39 deletions.
72 changes: 45 additions & 27 deletions src/Neo.Compiler.CSharp/CompilationContext.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (C) 2015-2022 The Neo Project.
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

Expand All @@ -13,6 +13,7 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Neo.Cryptography.ECC;
using Neo.Json;
using Neo.SmartContract;
Expand Down Expand Up @@ -327,15 +328,36 @@ public JObject CreateManifest()
};
}

public JObject CreateDebugInformation()
public JObject CreateDebugInformation(string folder = "")
{
string[] sourceLocations = GetSourceLocations(compilation).Distinct().ToArray();
return new JObject
List<string> documents = new();
List<JObject> methods = new();
foreach (var m in methodsConverted.Where(p => p.SyntaxNode is not null))
{
["hash"] = Script.ToScriptHash().ToString(),
["documents"] = sourceLocations.Select(p => (JString)p!).ToArray(),
["static-variables"] = staticFields.OrderBy(p => p.Value).Select(p => ((JString)$"{p.Key.Name},{p.Key.Type.GetContractParameterType()},{p.Value}")!).ToArray(),
["methods"] = methodsConverted.Where(p => p.SyntaxNode is not null).Select(m => new JObject
List<JString> sequencePoints = new();
foreach (var ins in m.Instructions.Where(i => i.SourceLocation is not null))
{
var doc = ins.SourceLocation!.SourceTree!.FilePath;
if (!string.IsNullOrEmpty(folder))
{
doc = Path.GetRelativePath(folder, doc);
}

var index = documents.IndexOf(doc);
if (index == -1)
{
index = documents.Count;
documents.Add(doc);
}

FileLinePositionSpan span = ins.SourceLocation!.GetLineSpan();
var str = $"{ins.Offset}[{index}]{ToRangeString(span.StartLinePosition)}-{ToRangeString(span.EndLinePosition)}";
sequencePoints.Add(new JString(str));

static string ToRangeString(LinePosition pos) => $"{pos.Line + 1}:{pos.Character + 1}";
}

methods.Add(new JObject
{
["id"] = m.Symbol.ToString(),
["name"] = $"{m.Symbol.ContainingType},{m.Symbol.Name}",
Expand All @@ -346,12 +368,17 @@ public JObject CreateDebugInformation()
.ToArray(),
["return"] = m.Symbol.ReturnType.GetContractParameterType().ToString(),
["variables"] = m.Variables.Select(p => ((JString)$"{p.Symbol.Name},{p.Symbol.Type.GetContractParameterType()},{p.SlotIndex}")!).ToArray(),
["sequence-points"] = m.Instructions.Where(p => p.SourceLocation is not null).Select(p =>
{
FileLinePositionSpan span = p.SourceLocation!.GetLineSpan();
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}")!;
}).ToArray()
}).ToArray(),
["sequence-points"] = sequencePoints.ToArray(),
});
}

return new JObject
{
["hash"] = Script.ToScriptHash().ToString(),
["documents"] = documents.Select(p => (JString)p!).ToArray(),
["document-root"] = string.IsNullOrEmpty(folder) ? JToken.Null : folder,
["static-variables"] = staticFields.OrderBy(p => p.Value).Select(p => ((JString)$"{p.Key.Name},{p.Key.Type.GetContractParameterType()},{p.Value}")!).ToArray(),
["methods"] = methods.ToArray(),
["events"] = eventsExported.Select(e => new JObject
{
["id"] = e.Name,
Expand All @@ -361,15 +388,6 @@ public JObject CreateDebugInformation()
};
}

private static IEnumerable<string> GetSourceLocations(Compilation compilation)
{
foreach (SyntaxTree syntaxTree in compilation.SyntaxTrees)
yield return syntaxTree.FilePath;
foreach (CompilationReference reference in compilation.References.OfType<CompilationReference>())
foreach (string path in GetSourceLocations(reference.Compilation))
yield return path;
}

private void ProcessCompilationUnit(HashSet<INamedTypeSymbol> processed, SemanticModel model, CompilationUnitSyntax syntax)
{
foreach (MemberDeclarationSyntax member in syntax.Members)
Expand Down
24 changes: 12 additions & 12 deletions src/Neo.Compiler.CSharp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (C) 2015-2022 The Neo Project.
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
//
// The Neo.Compiler.CSharp is free software distributed under the MIT
// software license, see the accompanying file LICENSE in the main directory
// of the project or http://www.opensource.org/licenses/mit-license.php
// for more details.
//
//
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

Expand Down Expand Up @@ -127,26 +127,26 @@ private static int ProcessOutputs(Options options, string folder, CompilationCon
if (context.Success)
{
string baseName = options.BaseName ?? context.ContractName!;
folder = options.Output ?? Path.Combine(folder, "bin", "sc");
Directory.CreateDirectory(folder);
string path = Path.Combine(folder, $"{baseName}.nef");
string outputFolder = options.Output ?? Path.Combine(folder, "bin", "sc");
Directory.CreateDirectory(outputFolder);
string path = Path.Combine(outputFolder, $"{baseName}.nef");
File.WriteAllBytes(path, context.CreateExecutable().ToArray());
Console.WriteLine($"Created {path}");
path = Path.Combine(folder, $"{baseName}.manifest.json");
path = Path.Combine(outputFolder, $"{baseName}.manifest.json");
File.WriteAllBytes(path, context.CreateManifest().ToByteArray(false));
Console.WriteLine($"Created {path}");
if (options.Debug)
{
path = Path.Combine(folder, $"{baseName}.nefdbgnfo");
path = Path.Combine(outputFolder, $"{baseName}.nefdbgnfo");
using FileStream fs = new(path, FileMode.Create, FileAccess.Write);
using ZipArchive archive = new(fs, ZipArchiveMode.Create);
using Stream stream = archive.CreateEntry($"{baseName}.debug.json").Open();
stream.Write(context.CreateDebugInformation().ToByteArray(false));
stream.Write(context.CreateDebugInformation(folder).ToByteArray(false));
Console.WriteLine($"Created {path}");
}
if (options.Assembly)
{
path = Path.Combine(folder, $"{baseName}.asm");
path = Path.Combine(outputFolder, $"{baseName}.asm");
File.WriteAllText(path, context.CreateAssembly());
Console.WriteLine($"Created {path}");
}
Expand Down

0 comments on commit 5412edb

Please sign in to comment.