diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Debugging/DebuggerSourceMap.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Debugging/DebuggerSourceMap.cs index 0a258c9f62..6cd8152ccb 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Debugging/DebuggerSourceMap.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Debugging/DebuggerSourceMap.cs @@ -73,6 +73,19 @@ void ISourceMap.Add(object item, SourceRange range) lock (_gate) { + // Map works on a last one wins basis. When we refresh the item for a range, + // just keep the last range + + // Remove old item instance for this range. + // Find the entry for the current range + var rangeItemEntry = _sourceByItem.FirstOrDefault(kv => kv.Value.Equals(range) && kv.Key.GetType().Equals(item.GetType())); + + if (rangeItemEntry.Key != null) + { + // If found, remove the outdated item from the map + _sourceByItem.Remove(rangeItemEntry.Key); + } + _sourceByItem[item] = range; _dirty = true; } diff --git a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/InterfaceConverter.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/InterfaceConverter.cs index 9e636b687a..914a7154ea 100644 --- a/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/InterfaceConverter.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Declarative/Converters/InterfaceConverter.cs @@ -24,7 +24,7 @@ public class InterfaceConverter : JsonConverter, IObservableConverter, IObser private readonly ResourceExplorer resourceExplorer; private readonly List observers = new List(); private readonly SourceContext sourceContext; - private readonly ConcurrentDictionary cachedRefDialogs = new ConcurrentDictionary(); + private readonly Dictionary cachedRefDialogs = new Dictionary(); /// /// Initializes a new instance of the class. @@ -203,9 +203,6 @@ public void RegisterObserver(IJsonLoadObserver observer) private static JToken TryAssignId(JToken jToken, SourceContext sourceContext) { - // This is the jToken we'll use to build the concrete type. - var tokenToBuild = jToken; - // If our JToken does not have an id, try to get an id from the resource explorer // in a best-effort manner. if (jToken is JObject jObj && !jObj.ContainsKey("id")) @@ -213,15 +210,13 @@ private static JToken TryAssignId(JToken jToken, SourceContext sourceContext) // Check if we have an id registered for this token if (sourceContext is ResourceSourceContext rsc && rsc.DefaultIdMap.ContainsKey(jToken)) { - // Clone the token since we'll alter it from the file version. - // If we don't clone, future ranges will be calculated based on the altered token. - // which will end in a wrong source range. - tokenToBuild = jToken.DeepClone(); - tokenToBuild["id"] = rsc.DefaultIdMap[jToken]; + // Just assign. Avoid cloning JTokens since Json.NET does not clone line info + // Tracking item on Json.NET: https://github.com/JamesNK/Newtonsoft.Json/issues/2410 + jToken["id"] = rsc.DefaultIdMap[jToken]; } } - return tokenToBuild; + return jToken; } } }