diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c97263a..e69aa90 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -33,7 +33,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: npm install @@ -62,7 +62,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: npm install @@ -91,7 +91,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: npm install @@ -161,7 +161,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: dotnet cake --target=test --configuration=release @@ -183,7 +183,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: dotnet cake --target=test --configuration=release @@ -205,7 +205,7 @@ stages: steps: - task: UseDotNet@2 inputs: - version: '8.x' + version: '9.x' - script: dotnet tool restore displayName: 'Restore .NET tools' - script: dotnet cake --target=test --configuration=release diff --git a/package.json b/package.json index 26e1a44..132dcbe 100644 --- a/package.json +++ b/package.json @@ -290,6 +290,13 @@ "Decimal", "Hexadecimal" ] + }, + "dotnetMeteor.debuggerOptions.sourceCodeMappings": { + "type": "object", + "description": "%configuration.description.debuggerOptions.sourceCodeMappings%", + "additionalProperties": { + "type": "string" + } } } } diff --git a/package.nls.json b/package.nls.json index d326e96..e308007 100644 --- a/package.nls.json +++ b/package.nls.json @@ -44,5 +44,6 @@ "configuration.description.debuggerOptions.stepOverPropertiesAndOperators": "Specifies whether the debugger should step over properties and operators.", "configuration.description.debuggerOptions.searchMicrosoftSymbolServer": "Search for symbols on the Microsoft Symbol Server.", "configuration.description.debuggerOptions.searchNuGetSymbolServer": "Search for symbols on the NuGet Symbol Server.", - "configuration.description.debuggerOptions.integerDisplayFormat": "Specifies the format of displayed integers in the debugging window." + "configuration.description.debuggerOptions.integerDisplayFormat": "Specifies the format of displayed integers in the debugging window.", + "configuration.description.debuggerOptions.sourceCodeMappings": "Modifies locations for the debugged source code by replacing values on the left with values on the right." } diff --git a/src/DotNet.Meteor.Debug/DebugOptions.cs b/src/DotNet.Meteor.Debug/DebugOptions.cs index 19fdd3f..c40bb8c 100644 --- a/src/DotNet.Meteor.Debug/DebugOptions.cs +++ b/src/DotNet.Meteor.Debug/DebugOptions.cs @@ -1,3 +1,4 @@ +using System.Collections.Immutable; using System.Text.Json.Serialization; using DotNet.Meteor.Debug.Extensions; using Mono.Debugging.Client; @@ -56,6 +57,9 @@ public class DebugOptions { [JsonPropertyName("search_nuget_symbol_server")] public bool SearchNuGetSymbolServer { get; set; } = ServerExtensions.DefaultDebuggerOptions.SearchNuGetSymbolServer; + [JsonPropertyName("source_code_mappings")] + public ImmutableDictionary SourceCodeMappings { get; set; } = ServerExtensions.DefaultDebuggerOptions.SourceCodeMappings; + internal static IntegerDisplayFormat GetIntegerDisplayFormat(string value) { if (value == Mono.Debugging.Client.IntegerDisplayFormat.Decimal.ToString()) return Mono.Debugging.Client.IntegerDisplayFormat.Decimal; diff --git a/src/DotNet.Meteor.Debug/DebugSession.cs b/src/DotNet.Meteor.Debug/DebugSession.cs index 5a1aafd..6720dd0 100644 --- a/src/DotNet.Meteor.Debug/DebugSession.cs +++ b/src/DotNet.Meteor.Debug/DebugSession.cs @@ -259,11 +259,12 @@ public class DebugSession : Session { } DebugProtocol.Source source = null; - if (!string.IsNullOrEmpty(frame.SourceLocation.FileName) && File.Exists(frame.SourceLocation.FileName)) { + string remappedSourcePath = session.RemapSourceLocation(frame.SourceLocation); + if (!string.IsNullOrEmpty(remappedSourcePath) && File.Exists(remappedSourcePath)) { source = new DebugProtocol.Source() { - Name = Path.GetFileName(frame.SourceLocation.FileName), + Name = Path.GetFileName(remappedSourcePath), PresentationHint = Source.PresentationHintValue.Normal, - Path = frame.SourceLocation.FileName, + Path = remappedSourcePath, SourceReference = 0 }; } diff --git a/src/DotNet.Meteor.Debug/Extensions/MonoExtensions.cs b/src/DotNet.Meteor.Debug/Extensions/MonoExtensions.cs index 96208c6..90962fd 100644 --- a/src/DotNet.Meteor.Debug/Extensions/MonoExtensions.cs +++ b/src/DotNet.Meteor.Debug/Extensions/MonoExtensions.cs @@ -56,6 +56,17 @@ public static class MonoExtensions { options.UseExternalTypeResolver = useExternalTypeResolver; return frame.GetExpressionValue(expression, options); } + public static string RemapSourceLocation(this SoftDebuggerSession session, SourceLocation location) { + if (location == null || string.IsNullOrEmpty(location.FileName)) + return null; + + foreach (var remap in session.Options.SourceCodeMappings) { + if (location.FileName.Contains(remap.Key)) + return location.FileName.Replace(remap.Key, remap.Value); + } + + return location.FileName; + } public static void SetUserAssemblyNames(this SoftDebuggerStartInfo startInfo, string assembliesDirectory, DebuggerSessionOptions options) { var includeSymbolServers = options.SearchMicrosoftSymbolServer || options.SearchNuGetSymbolServer; diff --git a/src/DotNet.Meteor.Debug/Extensions/SymbolServerExtensions.cs b/src/DotNet.Meteor.Debug/Extensions/SymbolServerExtensions.cs index 8536ff0..ddef26a 100644 --- a/src/DotNet.Meteor.Debug/Extensions/SymbolServerExtensions.cs +++ b/src/DotNet.Meteor.Debug/Extensions/SymbolServerExtensions.cs @@ -29,7 +29,12 @@ public static class SymbolServerExtensions { } public static string DownloadSourceFile(SourceLink link) { var sourcesDirectory = Path.Combine(tempDirectory, "sources"); - var outputFilePath = Path.Combine(sourcesDirectory, link.RelativeFilePath); + if (!Uri.TryCreate(link.Uri, UriKind.Absolute, out var sourceLinkUri)) { + DebuggerLoggingService.CustomLogger.LogMessage($"Invalid source link '{link.Uri}'"); + return null; + } + + var outputFilePath = Path.Combine(sourcesDirectory, sourceLinkUri.LocalPath.TrimStart('/')); if (File.Exists(outputFilePath)) return outputFilePath; diff --git a/src/DotNet.Meteor.Debug/LaunchConfiguration.cs b/src/DotNet.Meteor.Debug/LaunchConfiguration.cs index 5885c54..8003fba 100644 --- a/src/DotNet.Meteor.Debug/LaunchConfiguration.cs +++ b/src/DotNet.Meteor.Debug/LaunchConfiguration.cs @@ -97,6 +97,7 @@ public class LaunchConfiguration { debuggerOptions.StepOverPropertiesAndOperators = options.StepOverPropertiesAndOperators; debuggerOptions.SearchMicrosoftSymbolServer = options.SearchMicrosoftSymbolServer; debuggerOptions.SearchNuGetSymbolServer = options.SearchNuGetSymbolServer; + debuggerOptions.SourceCodeMappings = options.SourceCodeMappings; return debuggerOptions; } diff --git a/src/Mono.Debugger b/src/Mono.Debugger index 41c1376..496b68a 160000 --- a/src/Mono.Debugger +++ b/src/Mono.Debugger @@ -1 +1 @@ -Subproject commit 41c1376b5d92cffe059b6993565fb3ccb8a2a5c1 +Subproject commit 496b68a52b4c3ebb658f0360865990c2aaf2b6dd diff --git a/src/VSCode.Extension/configurationController.ts b/src/VSCode.Extension/configurationController.ts index 2a683fa..4096db6 100644 --- a/src/VSCode.Extension/configurationController.ts +++ b/src/VSCode.Extension/configurationController.ts @@ -60,7 +60,8 @@ export class ConfigurationController { ellipsized_length: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsEllipsizedLength), project_assemblies_only: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsProjectAssembliesOnly), step_over_properties_and_operators: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsStepOverPropertiesAndOperators), - search_microsoft_symbol_server: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsSearchMicrosoftSymbolServer) + search_microsoft_symbol_server: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsSearchMicrosoftSymbolServer), + source_code_mappings: ConfigurationController.getSettingOrDefault(res.configIdDebuggerOptionsSourceCodeMappings) }; } diff --git a/src/VSCode.Extension/resources/constants.ts b/src/VSCode.Extension/resources/constants.ts index f0dd801..ad19ace 100644 --- a/src/VSCode.Extension/resources/constants.ts +++ b/src/VSCode.Extension/resources/constants.ts @@ -68,4 +68,5 @@ export const configIdDebuggerOptionsEllipsizedLength = `${configIdDebuggerOption export const configIdDebuggerOptionsProjectAssembliesOnly = `${configIdDebuggerOptions}.projectAssembliesOnly`; export const configIdDebuggerOptionsStepOverPropertiesAndOperators = `${configIdDebuggerOptions}.stepOverPropertiesAndOperators`; export const configIdDebuggerOptionsSearchMicrosoftSymbolServer = `${configIdDebuggerOptions}.searchMicrosoftSymbolServer`; -export const configIdDebuggerOptionsSearchNuGetSymbolServer = `${configIdDebuggerOptions}.searchNugetSymbolServer`; \ No newline at end of file +export const configIdDebuggerOptionsSearchNuGetSymbolServer = `${configIdDebuggerOptions}.searchNugetSymbolServer`; +export const configIdDebuggerOptionsSourceCodeMappings = `${configIdDebuggerOptions}.sourceCodeMappings`; \ No newline at end of file