Skip to content

Commit 19a85f3

Browse files
committed
1. Improved performance of debugging in ActiveScript modes;
2. `GetSourceFragmentFromLine` method of `JsErrorHelpers` class has been replaced by the `GetTextFragmentFromLine` method of `TextHelpers` class.
1 parent ef42fb6 commit 19a85f3

File tree

10 files changed

+177
-116
lines changed

10 files changed

+177
-116
lines changed

src/MsieJavaScriptEngine/ActiveScript/ActiveScriptJsEngineBase.ScriptSiteBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ protected ActiveScriptException CreateActiveScriptException(IActiveScriptError e
130130
string sourceLine;
131131
error.GetSourceLineText(out sourceLine);
132132

133-
sourceFragment = JsErrorHelpers.GetSourceFragmentFromLine(sourceLine, columnNumber);
133+
sourceFragment = TextHelpers.GetTextFragmentFromLine(sourceLine, columnNumber);
134134
}
135135
else
136136
{

src/MsieJavaScriptEngine/ActiveScript/Debugging/DebugDocument.cs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Runtime.InteropServices;
6-
using System.Text.RegularExpressions;
6+
7+
using MsieJavaScriptEngine.Helpers;
78

89
namespace MsieJavaScriptEngine.ActiveScript.Debugging
910
{
@@ -13,11 +14,6 @@ namespace MsieJavaScriptEngine.ActiveScript.Debugging
1314
internal sealed class DebugDocument : IDebugDocumentInfo, IDebugDocumentProvider, IDebugDocument,
1415
IDebugDocumentText
1516
{
16-
/// <summary>
17-
/// Regular expression for working with a line break
18-
/// </summary>
19-
private static readonly Regex _lineBreakRegex = new Regex("\r\n|\n|\r");
20-
2117
/// <summary>
2218
/// Active Script wrapper
2319
/// </summary>
@@ -84,31 +80,6 @@ public DebugDocument(IActiveScriptWrapper activeScriptWrapper,
8480
}
8581

8682

87-
/// <summary>
88-
/// Finds a line break
89-
/// </summary>
90-
/// <param name="sourceCode">Source code</param>
91-
/// <param name="startPosition">Position in the input string that defines the leftmost
92-
/// position to be searched</param>
93-
/// <param name="length">Number of characters in the substring to include in the search</param>
94-
/// <param name="lineBreakPosition">Position of line break</param>
95-
/// <param name="lineBreakLength">Length of line break</param>
96-
private static void FindLineBreak(string sourceCode, int startPosition, int length,
97-
out int lineBreakPosition, out int lineBreakLength)
98-
{
99-
Match lineBreakMatch = _lineBreakRegex.Match(sourceCode, startPosition, length);
100-
if (lineBreakMatch.Success)
101-
{
102-
lineBreakPosition = lineBreakMatch.Index;
103-
lineBreakLength = lineBreakMatch.Length;
104-
}
105-
else
106-
{
107-
lineBreakPosition = -1;
108-
lineBreakLength = 0;
109-
}
110-
}
111-
11283
/// <summary>
11384
/// Initializes a debug document
11485
/// </summary>
@@ -126,7 +97,7 @@ private void Initialize()
12697
documentStartPosition : lineBreakPosition + lineBreakLength;
12798
int remainderLength = documentEndPosition - linePosition + 1;
12899

129-
FindLineBreak(_code, linePosition, remainderLength,
100+
TextHelpers.FindNextLineBreak(_code, linePosition, remainderLength,
130101
out lineBreakPosition, out lineBreakLength);
131102

132103
int lineLength = lineBreakPosition != -1 ? lineBreakPosition - linePosition : 0;

src/MsieJavaScriptEngine/Extensions/StringExtensions.cs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,5 +117,39 @@ public static string[] SplitToLines(this string source)
117117

118118
return result;
119119
}
120+
121+
/// <summary>
122+
/// Gets a character at the specified index from the string.
123+
/// A return value indicates whether the receiving succeeded.
124+
/// </summary>
125+
/// <param name="source">The source string</param>
126+
/// <param name="index">The zero-based index of the character</param>
127+
/// <param name="result">When this method returns, contains the character from the string,
128+
/// if the receiving succeeded, or null character if the receiving failed.
129+
/// The receiving fails if the index out of bounds.</param>
130+
/// <returns>true if the character was received successfully; otherwise, false</returns>
131+
public static bool TryGetChar(this string source, int index, out char result)
132+
{
133+
if (source == null)
134+
{
135+
throw new ArgumentNullException(nameof(source));
136+
}
137+
138+
bool isSuccess;
139+
int length = source.Length;
140+
141+
if (length > 0 && index >= 0 && index < length)
142+
{
143+
result = source[index];
144+
isSuccess = true;
145+
}
146+
else
147+
{
148+
result = '\0';
149+
isSuccess = false;
150+
}
151+
152+
return isSuccess;
153+
}
120154
}
121155
}

src/MsieJavaScriptEngine/Helpers/JsErrorHelpers.cs

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -455,75 +455,6 @@ public static JsEngineLoadException WrapEngineLoadException(Exception exception,
455455

456456
#region Misc
457457

458-
/// <summary>
459-
/// Gets a fragment from the source line
460-
/// </summary>
461-
/// <param name="sourceLine">Content of the source line</param>
462-
/// <param name="columnNumber">Column number</param>
463-
/// <param name="maxFragmentLength">Maximum length of the source fragment</param>
464-
public static string GetSourceFragmentFromLine(string sourceLine, int columnNumber,
465-
int maxFragmentLength = 100)
466-
{
467-
if (string.IsNullOrEmpty(sourceLine))
468-
{
469-
return string.Empty;
470-
}
471-
472-
string fragment;
473-
int lineLength = sourceLine.Length;
474-
475-
if (lineLength > maxFragmentLength)
476-
{
477-
const string ellipsisSymbol = "…";
478-
string startPart = string.Empty;
479-
string endPart = string.Empty;
480-
481-
var leftOffset = (int)Math.Floor((double)maxFragmentLength / 2);
482-
int fragmentStartPosition = columnNumber - leftOffset - 1;
483-
if (fragmentStartPosition > 0)
484-
{
485-
if (lineLength - fragmentStartPosition < maxFragmentLength)
486-
{
487-
fragmentStartPosition = lineLength - maxFragmentLength;
488-
}
489-
}
490-
else
491-
{
492-
fragmentStartPosition = 0;
493-
}
494-
int fragmentLength = maxFragmentLength;
495-
496-
if (fragmentStartPosition > 0)
497-
{
498-
startPart = ellipsisSymbol;
499-
}
500-
if (fragmentStartPosition + fragmentLength < lineLength)
501-
{
502-
endPart = ellipsisSymbol;
503-
}
504-
505-
StringBuilder fragmentBuilder = StringBuilderPool.GetBuilder();
506-
if (startPart.Length > 0)
507-
{
508-
fragmentBuilder.Append(startPart);
509-
}
510-
fragmentBuilder.Append(sourceLine.Substring(fragmentStartPosition, fragmentLength));
511-
if (endPart.Length > 0)
512-
{
513-
fragmentBuilder.Append(endPart);
514-
}
515-
516-
fragment = fragmentBuilder.ToString();
517-
StringBuilderPool.ReleaseBuilder(fragmentBuilder);
518-
}
519-
else
520-
{
521-
fragment = sourceLine;
522-
}
523-
524-
return fragment;
525-
}
526-
527458
/// <summary>
528459
/// Writes a error location line to the buffer
529460
/// </summary>
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
using System;
2+
using System.Text;
3+
4+
using MsieJavaScriptEngine.Extensions;
5+
using MsieJavaScriptEngine.Utilities;
6+
7+
namespace MsieJavaScriptEngine.Helpers
8+
{
9+
/// <summary>
10+
/// Text helpers
11+
/// </summary>
12+
public static class TextHelpers
13+
{
14+
/// <summary>
15+
/// Array of characters used to find the next line break
16+
/// </summary>
17+
private static readonly char[] _nextLineBreakChars = new char[] { '\r', '\n' };
18+
19+
20+
/// <summary>
21+
/// Gets a fragment from the text line
22+
/// </summary>
23+
/// <param name="textLine">Content of the text line</param>
24+
/// <param name="columnNumber">Column number</param>
25+
/// <param name="maxFragmentLength">Maximum length of the text fragment</param>
26+
public static string GetTextFragmentFromLine(string textLine, int columnNumber,
27+
int maxFragmentLength = 100)
28+
{
29+
if (string.IsNullOrEmpty(textLine))
30+
{
31+
return string.Empty;
32+
}
33+
34+
string fragment;
35+
int lineLength = textLine.Length;
36+
37+
if (lineLength > maxFragmentLength)
38+
{
39+
const string ellipsisSymbol = "…";
40+
string startPart = string.Empty;
41+
string endPart = string.Empty;
42+
43+
var leftOffset = (int)Math.Floor((double)maxFragmentLength / 2);
44+
int fragmentStartPosition = columnNumber - leftOffset - 1;
45+
if (fragmentStartPosition > 0)
46+
{
47+
if (lineLength - fragmentStartPosition < maxFragmentLength)
48+
{
49+
fragmentStartPosition = lineLength - maxFragmentLength;
50+
}
51+
}
52+
else
53+
{
54+
fragmentStartPosition = 0;
55+
}
56+
int fragmentLength = maxFragmentLength;
57+
58+
if (fragmentStartPosition > 0)
59+
{
60+
startPart = ellipsisSymbol;
61+
}
62+
if (fragmentStartPosition + fragmentLength < lineLength)
63+
{
64+
endPart = ellipsisSymbol;
65+
}
66+
67+
StringBuilder fragmentBuilder = StringBuilderPool.GetBuilder();
68+
if (startPart.Length > 0)
69+
{
70+
fragmentBuilder.Append(startPart);
71+
}
72+
fragmentBuilder.Append(textLine.Substring(fragmentStartPosition, fragmentLength));
73+
if (endPart.Length > 0)
74+
{
75+
fragmentBuilder.Append(endPart);
76+
}
77+
78+
fragment = fragmentBuilder.ToString();
79+
StringBuilderPool.ReleaseBuilder(fragmentBuilder);
80+
}
81+
else
82+
{
83+
fragment = textLine;
84+
}
85+
86+
return fragment;
87+
}
88+
89+
/// <summary>
90+
/// Finds a next line break
91+
/// </summary>
92+
/// <param name="sourceText">Source text</param>
93+
/// <param name="startPosition">Position in the input string that defines the leftmost
94+
/// position to be searched</param>
95+
/// <param name="length">Number of characters in the substring to include in the search</param>
96+
/// <param name="lineBreakPosition">Position of line break</param>
97+
/// <param name="lineBreakLength">Length of line break</param>
98+
internal static void FindNextLineBreak(string sourceText, int startPosition, int length,
99+
out int lineBreakPosition, out int lineBreakLength)
100+
{
101+
lineBreakPosition = sourceText.IndexOfAny(_nextLineBreakChars, startPosition, length);
102+
if (lineBreakPosition != -1)
103+
{
104+
lineBreakLength = 1;
105+
char currentCharacter = sourceText[lineBreakPosition];
106+
107+
if (currentCharacter == '\r')
108+
{
109+
int nextCharacterPosition = lineBreakPosition + 1;
110+
char nextCharacter;
111+
112+
if (sourceText.TryGetChar(nextCharacterPosition, out nextCharacter)
113+
&& nextCharacter == '\n')
114+
{
115+
lineBreakLength = 2;
116+
}
117+
}
118+
}
119+
else
120+
{
121+
lineBreakLength = 0;
122+
}
123+
}
124+
}
125+
}

src/MsieJavaScriptEngine/JsRt/Edge/ChakraEdgeJsRtJsEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ private WrapperException WrapJsException(OriginalException originalException,
951951
sourceLine = sourcePropertyValue.ConvertToString().ToString();
952952
}
953953

954-
sourceFragment = JsErrorHelpers.GetSourceFragmentFromLine(sourceLine, columnNumber);
954+
sourceFragment = TextHelpers.GetTextFragmentFromLine(sourceLine, columnNumber);
955955
message = JsErrorHelpers.GenerateScriptErrorMessage(type, description, documentName,
956956
lineNumber, columnNumber, sourceFragment);
957957
}

src/MsieJavaScriptEngine/JsRt/Ie/ChakraIeJsRtJsEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,7 +978,7 @@ private WrapperException WrapJsException(OriginalException originalException,
978978
sourceLine = sourcePropertyValue.ConvertToString().ToString();
979979
}
980980

981-
sourceFragment = JsErrorHelpers.GetSourceFragmentFromLine(sourceLine, columnNumber);
981+
sourceFragment = TextHelpers.GetTextFragmentFromLine(sourceLine, columnNumber);
982982
message = JsErrorHelpers.GenerateScriptErrorMessage(type, description, documentName,
983983
lineNumber, columnNumber, sourceFragment);
984984
}

src/MsieJavaScriptEngine/MsieJavaScriptEngine.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
<RepositoryUrl>https://github.com/Taritsyn/MsieJavaScriptEngine</RepositoryUrl>
2525
<RepositoryType>git</RepositoryType>
2626
<PackageTags>JavaScript;ECMAScript;MSIE;IE;Edge;Chakra</PackageTags>
27-
<PackageReleaseNotes>1. In JavaScript engine settings was added one new property - `MaxStackSize` (default `492` or `984` KB);
28-
2. JSON2 library was updated to version of June 12, 2017.</PackageReleaseNotes>
27+
<PackageReleaseNotes>1. Improved performance of debugging in ActiveScript modes;
28+
2. `GetSourceFragmentFromLine` method of `JsErrorHelpers` class has been replaced by the `GetTextFragmentFromLine` method of `TextHelpers` class.</PackageReleaseNotes>
2929
<NeutralLanguage>en-US</NeutralLanguage>
3030
<PackageOutputPath>../../nuget</PackageOutputPath>
3131
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

src/MsieJavaScriptEngine/readme.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
=============
2222
RELEASE NOTES
2323
=============
24-
1. In JavaScript engine settings was added one new property - `MaxStackSize`
25-
(default `492` or `984` KB);
26-
2. JSON2 library was updated to version of June 12, 2017.
24+
1. Improved performance of debugging in ActiveScript modes;
25+
2. `GetSourceFragmentFromLine` method of `JsErrorHelpers` class has been
26+
replaced by the `GetTextFragmentFromLine` method of `TextHelpers` class.
2727

2828
============
2929
PROJECT SITE

test/MsieJavaScriptEngine.Test.Common/ErrorFormattingTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ public void GettingSourceFragmentFromLineIsCorrect()
5454
"case 2:enc=enc.slice(0,-1)+'=';break}return @enc}";
5555

5656
// Act
57-
string output1 = JsErrorHelpers.GetSourceFragmentFromLine(input1, 1, 100);
58-
string output2 = JsErrorHelpers.GetSourceFragmentFromLine(input2, 1, 100);
59-
string output3 = JsErrorHelpers.GetSourceFragmentFromLine(input3, 5, 100);
60-
string output4 = JsErrorHelpers.GetSourceFragmentFromLine(input4, 70, 85);
61-
string output5 = JsErrorHelpers.GetSourceFragmentFromLine(input5, 145, 100);
62-
string output6 = JsErrorHelpers.GetSourceFragmentFromLine(input6, 23, 100);
63-
string output7 = JsErrorHelpers.GetSourceFragmentFromLine(input7, 465, 100);
57+
string output1 = TextHelpers.GetTextFragmentFromLine(input1, 1, 100);
58+
string output2 = TextHelpers.GetTextFragmentFromLine(input2, 1, 100);
59+
string output3 = TextHelpers.GetTextFragmentFromLine(input3, 5, 100);
60+
string output4 = TextHelpers.GetTextFragmentFromLine(input4, 70, 85);
61+
string output5 = TextHelpers.GetTextFragmentFromLine(input5, 145, 100);
62+
string output6 = TextHelpers.GetTextFragmentFromLine(input6, 23, 100);
63+
string output7 = TextHelpers.GetTextFragmentFromLine(input7, 465, 100);
6464

6565
// Assert
6666
Assert.AreEqual(targetOutput1, output1);

0 commit comments

Comments
 (0)