From c90b986d8b1ee55505b01056c4a772cfc5b210b6 Mon Sep 17 00:00:00 2001 From: Aleric Inglewood Date: Wed, 28 May 2014 18:51:17 +0200 Subject: [PATCH] Improved line map heuristics. If the C# column can't be found in the positionMap (but the line can), use the map immediately after it while correcting for the offset, unless that results in an LSL position before the previous LSL position in the positionMap. The idea behind this heuristic is that in most, if not all cases C# consumes more characters than LSL (for example LSL_Types.LSLInteger instead of just 'integer'). Thus if the distance between the columns of two markers differ in the C# and LSL file, the distance in the C# file will be larger. Moreover, we can assume that every time this happens we will have a marker at the beginning of the longer 'keyword', because those keywords were generated by us in the first place. For example: C#: LSL_Types.LSLInteger f2(LSL_Types.LSLString s) ^ ^ 1 2 will always have markers at the beginning of the long keywords 'LSL_Types.LSLInteger' and 'LSL_Types.LSLString'. If an error is generated in between (for example at the beginning of the function name 'f2') then the correct position is found by using an offset relative to 2 rather than 1. Note that a case where this isn't working correctly is when the user adds extra spaces. For example: LSL: integer f2( string s) would still use the start of 'string' as reference and then go backwards 3 characters only because the corresponding C# still looks like C#: LSL_Types.LSLInteger f2(LSL_Types.LSLString s) ^ ^ only 3 chars difference and the reported error at 'f2' would be here: LSL: integer f2( string s) ^ This can only be fixed by generating a mapping for 'f2' itself, or generating a mapping whenever the amount of spaces is changed. --- .../ScriptEngine/Shared/CodeTools/Compiler.cs | 56 +++++++++++++------ OpenSim/Tools/Compiler/Program.cs | 56 +++++++++++++------ 2 files changed, 80 insertions(+), 32 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs index 0b41bc6baf..5988539ada 100644 --- a/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs +++ b/OpenSim/Region/ScriptEngine/Shared/CodeTools/Compiler.cs @@ -724,13 +724,13 @@ namespace SecondLife return assembly; } - private class kvpSorter : IComparer> + private class kvpSorter : IComparer, KeyValuePair>> { - public int Compare(KeyValuePair a, - KeyValuePair b) + public int Compare(KeyValuePair, KeyValuePair> a, + KeyValuePair, KeyValuePair> b) { - int kc = a.Key.CompareTo(b.Key); - return (kc != 0) ? kc : a.Value.CompareTo(b.Value); + int kc = a.Key.Key.CompareTo(b.Key.Key); + return (kc != 0) ? kc : a.Key.Value.CompareTo(b.Key.Value); } } @@ -747,24 +747,48 @@ namespace SecondLife out ret)) return ret; - List> sorted = - new List>(positionMap.Keys); + var sorted = new List, KeyValuePair>>(positionMap); sorted.Sort(new kvpSorter()); - int l = sorted[0].Key; - int c = sorted[0].Value; + int l = 1; + int c = 1; + int pl = 1; - foreach (KeyValuePair cspos in sorted) + foreach (KeyValuePair, KeyValuePair> posmap in sorted) { - if (cspos.Key >= line && - !(cspos.Key == line && cspos.Value <= col)) + //m_log.DebugFormat("[Compiler]: Scanning line map {0},{1} --> {2},{3}", posmap.Key.Key, posmap.Key.Value, posmap.Value.Key, posmap.Value.Value); + int nl = posmap.Value.Key + line - posmap.Key.Key; // New, translated LSL line and column. + int nc = posmap.Value.Value + col - posmap.Key.Value; + // Keep going until we find the first point passed line,col. + if (posmap.Key.Key > line) + { + //m_log.DebugFormat("[Compiler]: Line is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); + if (pl < line) + { + //m_log.DebugFormat("[Compiler]: Previous line ({0}) is less than requested line ({1}), setting column to 1.", pl, line); + c = 1; + } break; - l = cspos.Key; - c = cspos.Value; + } + if (posmap.Key.Key == line && posmap.Key.Value > col) + { + // Never move l,c backwards. + if (nl > l || (nl == l && nc > c)) + { + //m_log.DebugFormat("[Compiler]: Using offset relative to this: {0} + {1} - {2}, {3} + {4} - {5} = {6}, {7}", + // posmap.Value.Key, line, posmap.Key.Key, posmap.Value.Value, col, posmap.Key.Value, nl, nc); + l = nl; + c = nc; + } + //m_log.DebugFormat("[Compiler]: Column is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); + break; + } + pl = posmap.Key.Key; + l = posmap.Value.Key; + c = posmap.Value.Value; } - positionMap.TryGetValue(new KeyValuePair(l, c), out ret); - return ret; + return new KeyValuePair(l, c); } string ReplaceTypes(string message) diff --git a/OpenSim/Tools/Compiler/Program.cs b/OpenSim/Tools/Compiler/Program.cs index b9c960b532..b010eaf7fe 100644 --- a/OpenSim/Tools/Compiler/Program.cs +++ b/OpenSim/Tools/Compiler/Program.cs @@ -255,13 +255,13 @@ namespace OpenSim.Tools.LSL.Compiler return FindErrorPosition(line, col, null); } - private class kvpSorter : IComparer> + private class kvpSorter : IComparer, KeyValuePair>> { - public int Compare(KeyValuePair a, - KeyValuePair b) + public int Compare(KeyValuePair, KeyValuePair> a, + KeyValuePair, KeyValuePair> b) { - int kc = a.Key.CompareTo(b.Key); - return (kc != 0) ? kc : a.Value.CompareTo(b.Value); + int kc = a.Key.Key.CompareTo(b.Key.Key); + return (kc != 0) ? kc : a.Key.Value.CompareTo(b.Key.Value); } } @@ -278,24 +278,48 @@ namespace OpenSim.Tools.LSL.Compiler out ret)) return ret; - List> sorted = - new List>(positionMap.Keys); + var sorted = new List, KeyValuePair>>(positionMap); sorted.Sort(new kvpSorter()); - int l = sorted[0].Key; - int c = sorted[0].Value; + int l = 1; + int c = 1; + int pl = 1; - foreach (KeyValuePair cspos in sorted) + foreach (KeyValuePair, KeyValuePair> posmap in sorted) { - if (cspos.Key >= line && - !(cspos.Key == line && cspos.Value <= col)) + //m_log.DebugFormat("[Compiler]: Scanning line map {0},{1} --> {2},{3}", posmap.Key.Key, posmap.Key.Value, posmap.Value.Key, posmap.Value.Value); + int nl = posmap.Value.Key + line - posmap.Key.Key; // New, translated LSL line and column. + int nc = posmap.Value.Value + col - posmap.Key.Value; + // Keep going until we find the first point passed line,col. + if (posmap.Key.Key > line) + { + //m_log.DebugFormat("[Compiler]: Line is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); + if (pl < line) + { + //m_log.DebugFormat("[Compiler]: Previous line ({0}) is less than requested line ({1}), setting column to 1.", pl, line); + c = 1; + } break; - l = cspos.Key; - c = cspos.Value; + } + if (posmap.Key.Key == line && posmap.Key.Value > col) + { + // Never move l,c backwards. + if (nl > l || (nl == l && nc > c)) + { + //m_log.DebugFormat("[Compiler]: Using offset relative to this: {0} + {1} - {2}, {3} + {4} - {5} = {6}, {7}", + // posmap.Value.Key, line, posmap.Key.Key, posmap.Value.Value, col, posmap.Key.Value, nl, nc); + l = nl; + c = nc; + } + //m_log.DebugFormat("[Compiler]: Column is larger than requested {0},{1}, returning {2},{3}", line, col, l, c); + break; + } + pl = posmap.Key.Key; + l = posmap.Value.Key; + c = posmap.Value.Value; } - positionMap.TryGetValue(new KeyValuePair(l, c), out ret); - return ret; + return new KeyValuePair(l, c); } } }