populate GlobalCode.sourceMaps
This commit is contained in:
@@ -113,6 +113,34 @@ public static unsafe class SlangExtensions
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public static unsafe List<SourceMapEntry> ToList(this Vec_FfiSourceMapEntry_t vec)
|
||||
{
|
||||
var toReturn = new List<SourceMapEntry>((int)vec.len);
|
||||
|
||||
var currentPtr = vec.ptr;
|
||||
|
||||
for (int i = 0; i < (int)vec.len; i++)
|
||||
{
|
||||
var item = currentPtr[i];
|
||||
|
||||
toReturn.Add(
|
||||
new SourceMapEntry
|
||||
{
|
||||
Ic10Line = item.line_number,
|
||||
SlangSource = new Range
|
||||
{
|
||||
EndCol = item.span.end_col,
|
||||
EndLine = item.span.end_line,
|
||||
StartCol = item.span.start_col,
|
||||
StartLine = item.span.start_line,
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
private static uint GetColorForKind(uint kind)
|
||||
{
|
||||
switch (kind)
|
||||
|
||||
@@ -71,18 +71,6 @@ public unsafe struct Vec_uint8_t {
|
||||
public UIntPtr cap;
|
||||
}
|
||||
|
||||
public unsafe partial class Ffi {
|
||||
/// <summary>
|
||||
/// C# handles strings as UTF16. We do NOT want to allocate that memory in C# because
|
||||
/// we want to avoid GC. So we pass it to Rust to handle all the memory allocations.
|
||||
/// This should result in the ability to compile many times without triggering frame drops
|
||||
/// from the GC from a <c>GetBytes()</c> call on a string in C#.
|
||||
/// </summary>
|
||||
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
|
||||
Vec_uint8_t compile_from_string (
|
||||
slice_ref_uint16_t input);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 16)]
|
||||
public unsafe struct FfiRange_t {
|
||||
public UInt32 start_col;
|
||||
@@ -94,6 +82,44 @@ public unsafe struct FfiRange_t {
|
||||
public UInt32 end_line;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 20)]
|
||||
public unsafe struct FfiSourceMapEntry_t {
|
||||
public UInt32 line_number;
|
||||
|
||||
public FfiRange_t span;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Same as [<c>Vec<T></c>][<c>rust::Vec</c>], but with guaranteed <c>#[repr(C)]</c> layout
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential, Size = 24)]
|
||||
public unsafe struct Vec_FfiSourceMapEntry_t {
|
||||
public FfiSourceMapEntry_t * ptr;
|
||||
|
||||
public UIntPtr len;
|
||||
|
||||
public UIntPtr cap;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 48)]
|
||||
public unsafe struct FfiCompilationResult_t {
|
||||
public Vec_uint8_t output_code;
|
||||
|
||||
public Vec_FfiSourceMapEntry_t source_map;
|
||||
}
|
||||
|
||||
public unsafe partial class Ffi {
|
||||
/// <summary>
|
||||
/// C# handles strings as UTF16. We do NOT want to allocate that memory in C# because
|
||||
/// we want to avoid GC. So we pass it to Rust to handle all the memory allocations.
|
||||
/// This should result in the ability to compile many times without triggering frame drops
|
||||
/// from the GC from a <c>GetBytes()</c> call on a string in C#.
|
||||
/// </summary>
|
||||
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
|
||||
FfiCompilationResult_t compile_from_string (
|
||||
slice_ref_uint16_t input);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Size = 48)]
|
||||
public unsafe struct FfiDiagnostic_t {
|
||||
public Vec_uint8_t message;
|
||||
@@ -146,6 +172,12 @@ public unsafe partial class Ffi {
|
||||
Vec_FfiDocumentedItem_t v);
|
||||
}
|
||||
|
||||
public unsafe partial class Ffi {
|
||||
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
|
||||
void free_ffi_compilation_result (
|
||||
FfiCompilationResult_t input);
|
||||
}
|
||||
|
||||
public unsafe partial class Ffi {
|
||||
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
|
||||
void free_ffi_diagnostic_vec (
|
||||
|
||||
@@ -15,11 +15,29 @@ public static class GlobalCode
|
||||
// so that save file data is smaller
|
||||
private static Dictionary<Guid, string> codeDict = new();
|
||||
|
||||
private static Dictionary<Guid, Dictionary<uint, List<Range>>> sourceMaps = new();
|
||||
|
||||
public static void ClearCache()
|
||||
{
|
||||
codeDict.Clear();
|
||||
}
|
||||
|
||||
public static void SetSourceMap(Guid reference, List<SourceMapEntry> sourceMapEntries)
|
||||
{
|
||||
var builtDictionary = new Dictionary<uint, List<Range>>();
|
||||
|
||||
foreach (var entry in sourceMapEntries)
|
||||
{
|
||||
if (!builtDictionary.ContainsKey(entry.Ic10Line))
|
||||
{
|
||||
builtDictionary[entry.Ic10Line] = new();
|
||||
}
|
||||
builtDictionary[entry.Ic10Line].Add(entry.SlangSource);
|
||||
}
|
||||
|
||||
sourceMaps[reference] = builtDictionary;
|
||||
}
|
||||
|
||||
public static string GetSource(Guid reference)
|
||||
{
|
||||
if (!codeDict.ContainsKey(reference))
|
||||
|
||||
@@ -23,6 +23,12 @@ public struct Diagnostic
|
||||
public Range Range;
|
||||
}
|
||||
|
||||
public struct SourceMapEntry
|
||||
{
|
||||
public Range SlangSource;
|
||||
public uint Ic10Line;
|
||||
}
|
||||
|
||||
public static class Marshal
|
||||
{
|
||||
private static IntPtr _libraryHandle = IntPtr.Zero;
|
||||
@@ -78,11 +84,16 @@ public static class Marshal
|
||||
}
|
||||
}
|
||||
|
||||
public static unsafe bool CompileFromString(string inputString, out string compiledString)
|
||||
public static unsafe bool CompileFromString(
|
||||
string inputString,
|
||||
out string compiledString,
|
||||
out List<SourceMapEntry> sourceMapEntries
|
||||
)
|
||||
{
|
||||
if (String.IsNullOrEmpty(inputString) || !EnsureLibLoaded())
|
||||
{
|
||||
compiledString = String.Empty;
|
||||
sourceMapEntries = new();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -95,19 +106,16 @@ public static class Marshal
|
||||
};
|
||||
|
||||
var result = Ffi.compile_from_string(input);
|
||||
|
||||
try
|
||||
{
|
||||
if ((ulong)result.len < 1)
|
||||
{
|
||||
compiledString = String.Empty;
|
||||
return false;
|
||||
}
|
||||
compiledString = result.AsString();
|
||||
sourceMapEntries = result.source_map.ToList();
|
||||
compiledString = result.output_code.AsString();
|
||||
return true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
result.Drop();
|
||||
Ffi.free_ffi_compilation_result(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public static class SlangPatches
|
||||
// guard to ensure we have valid IC10 before continuing
|
||||
if (
|
||||
!SlangPlugin.IsSlangSource(ref result)
|
||||
|| !Marshal.CompileFromString(result, out string compiled)
|
||||
|| !Marshal.CompileFromString(result, out var compiled, out var sourceMap)
|
||||
|| string.IsNullOrEmpty(compiled)
|
||||
)
|
||||
{
|
||||
@@ -37,6 +37,7 @@ public static class SlangPatches
|
||||
|
||||
// Ensure we cache this compiled code for later retreival.
|
||||
GlobalCode.SetSource(thisRef, result);
|
||||
GlobalCode.SetSourceMap(thisRef, sourceMap);
|
||||
|
||||
_currentlyEditingGuid = null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user