Skip to content

Commit 47d38ae

Browse files
committed
Was unified a generation of unique document names
1 parent 20eafca commit 47d38ae

File tree

10 files changed

+277
-49
lines changed

10 files changed

+277
-49
lines changed

src/JavaScriptEngineSwitcher.ChakraCore/ChakraCoreJsEngine.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ public sealed class ChakraCoreJsEngine : JsEngineBase
6767
/// </summary>
6868
private readonly ScriptDispatcher _dispatcher = new ScriptDispatcher();
6969

70+
/// <summary>
71+
/// Unique document name manager
72+
/// </summary>
73+
private readonly UniqueDocumentNameManager _documentNameManager =
74+
new UniqueDocumentNameManager(DefaultDocumentName);
75+
7076
/// <summary>
7177
/// Gets a name of JS engine
7278
/// </summary>
@@ -949,14 +955,16 @@ private static JsRuntimeException ConvertJsExceptionToJsRuntimeException(
949955

950956
protected override object InnerEvaluate(string expression)
951957
{
952-
return InnerEvaluate(expression, string.Empty);
958+
return InnerEvaluate(expression, null);
953959
}
954960

955961
protected override object InnerEvaluate(string expression, string documentName)
956962
{
963+
string uniqueDocumentName = _documentNameManager.GetUniqueName(documentName);
964+
957965
object result = InvokeScript(() =>
958966
{
959-
JsValue resultValue = JsContext.RunScript(expression, _jsSourceContext++, documentName);
967+
JsValue resultValue = JsContext.RunScript(expression, _jsSourceContext++, uniqueDocumentName);
960968

961969
return MapToHostType(resultValue);
962970
});
@@ -966,7 +974,7 @@ protected override object InnerEvaluate(string expression, string documentName)
966974

967975
protected override T InnerEvaluate<T>(string expression)
968976
{
969-
return InnerEvaluate<T>(expression, string.Empty);
977+
return InnerEvaluate<T>(expression, null);
970978
}
971979

972980
protected override T InnerEvaluate<T>(string expression, string documentName)
@@ -978,12 +986,14 @@ protected override T InnerEvaluate<T>(string expression, string documentName)
978986

979987
protected override void InnerExecute(string code)
980988
{
981-
InnerExecute(code, string.Empty);
989+
InnerExecute(code, null);
982990
}
983991

984992
protected override void InnerExecute(string code, string documentName)
985993
{
986-
InvokeScript(() => JsContext.RunScript(code, _jsSourceContext++, documentName));
994+
string uniqueDocumentName = _documentNameManager.GetUniqueName(documentName);
995+
996+
InvokeScript(() => JsContext.RunScript(code, _jsSourceContext++, uniqueDocumentName));
987997
}
988998

989999
protected override object InnerCallFunction(string functionName, params object[] args)

src/JavaScriptEngineSwitcher.Core.Net4/JavaScriptEngineSwitcher.Core.Net40.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@
110110
<Compile Include="..\JavaScriptEngineSwitcher.Core\Utilities\TypeExtensions.cs">
111111
<Link>Utilities\TypeExtensions.cs</Link>
112112
</Compile>
113+
<Compile Include="..\JavaScriptEngineSwitcher.Core\Utilities\UniqueDocumentNameManager.cs">
114+
<Link>Utilities\UniqueDocumentNameManager.cs</Link>
115+
</Compile>
113116
<Compile Include="..\JavaScriptEngineSwitcher.Core\Utilities\Utils.cs">
114117
<Link>Utilities\Utils.cs</Link>
115118
</Compile>

src/JavaScriptEngineSwitcher.Core/JsEngineBase.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ namespace JavaScriptEngineSwitcher.Core
1313
/// </summary>
1414
public abstract class JsEngineBase : IJsEngine
1515
{
16+
/// <summary>
17+
/// Default document name
18+
/// </summary>
19+
protected const string DefaultDocumentName = "Script Document";
20+
1621
/// <summary>
1722
/// Flag that object is destroyed
1823
/// </summary>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
5+
using JavaScriptEngineSwitcher.Core.Resources;
6+
7+
namespace JavaScriptEngineSwitcher.Core.Utilities
8+
{
9+
/// <summary>
10+
/// Unique document name manager
11+
/// </summary>
12+
public sealed class UniqueDocumentNameManager
13+
{
14+
/// <summary>
15+
/// Default document name
16+
/// </summary>
17+
private readonly string _defaultName;
18+
19+
/// <summary>
20+
/// Storage of unique names
21+
/// </summary>
22+
private readonly Dictionary<string, uint> _storage = new Dictionary<string, uint>();
23+
24+
/// <summary>
25+
/// Synchronizer of unique name storage
26+
/// </summary>
27+
private readonly object _storageSynchronizer = new object();
28+
29+
30+
/// <summary>
31+
/// Constructs an instance of the unique document name manager
32+
/// </summary>
33+
/// <param name="defaultName">Default document name</param>
34+
public UniqueDocumentNameManager(string defaultName)
35+
{
36+
if (defaultName == null)
37+
{
38+
throw new ArgumentNullException(
39+
"defaultName", string.Format(Strings.Common_ArgumentIsNull, "defaultName"));
40+
}
41+
42+
if (string.IsNullOrWhiteSpace(defaultName))
43+
{
44+
throw new ArgumentException(
45+
string.Format(Strings.Common_ArgumentIsEmpty, "defaultName"), "defaultName");
46+
}
47+
48+
_defaultName = defaultName;
49+
}
50+
51+
52+
/// <summary>
53+
/// Gets a unique document name
54+
/// </summary>
55+
/// <param name="name">Document name</param>
56+
/// <returns>Unique document name</returns>
57+
public string GetUniqueName(string name)
58+
{
59+
string appropriateName = !string.IsNullOrWhiteSpace(name) ?
60+
Path.GetFileNameWithoutExtension(name) : _defaultName;
61+
string extension = Path.GetExtension(name);
62+
63+
lock (_storageSynchronizer)
64+
{
65+
uint count;
66+
_storage.TryGetValue(appropriateName, out count);
67+
_storage[appropriateName] = ++count;
68+
69+
string uniqueName = count > 1 ?
70+
string.Concat(appropriateName, " [", count, "]", extension)
71+
:
72+
string.Concat(appropriateName, extension)
73+
;
74+
75+
return uniqueName;
76+
}
77+
}
78+
}
79+
}

src/JavaScriptEngineSwitcher.Jint/JintJsEngine.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public sealed class JintJsEngine : JsEngineBase
4545
/// </summary>
4646
private readonly object _executionSynchronizer = new object();
4747

48+
/// <summary>
49+
/// Unique document name manager
50+
/// </summary>
51+
private readonly UniqueDocumentNameManager _documentNameManager =
52+
new UniqueDocumentNameManager(DefaultDocumentName);
53+
4854
/// <summary>
4955
/// Gets a name of JS engine
5056
/// </summary>
@@ -273,6 +279,7 @@ protected override object InnerEvaluate(string expression)
273279
protected override object InnerEvaluate(string expression, string documentName)
274280
{
275281
object result;
282+
string uniqueDocumentName = _documentNameManager.GetUniqueName(documentName);
276283

277284
lock (_executionSynchronizer)
278285
{
@@ -282,7 +289,7 @@ protected override object InnerEvaluate(string expression, string documentName)
282289
{
283290
var parserOptions = new OriginalParserOptions
284291
{
285-
Source = documentName
292+
Source = uniqueDocumentName
286293
};
287294
resultValue = _jsEngine.Execute(expression, parserOptions).GetCompletionValue();
288295
}
@@ -332,13 +339,15 @@ protected override void InnerExecute(string code)
332339

333340
protected override void InnerExecute(string code, string documentName)
334341
{
342+
string uniqueDocumentName = _documentNameManager.GetUniqueName(documentName);
343+
335344
lock (_executionSynchronizer)
336345
{
337346
try
338347
{
339348
var parserOptions = new OriginalParserOptions
340349
{
341-
Source = documentName
350+
Source = uniqueDocumentName
342351
};
343352
_jsEngine.Execute(code, parserOptions);
344353
}

src/JavaScriptEngineSwitcher.Jurassic.Net4/JavaScriptEngineSwitcher.Jurassic.Net40.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@
5656
</None>
5757
</ItemGroup>
5858
<ItemGroup>
59+
<Compile Include="..\JavaScriptEngineSwitcher.Jurassic\FileScriptSource.cs">
60+
<Link>FileScriptSource.cs</Link>
61+
</Compile>
5962
<Compile Include="..\JavaScriptEngineSwitcher.Jurassic\JsEngineFactoryCollectionExtensions.cs">
6063
<Link>JsEngineFactoryCollectionExtensions.cs</Link>
6164
</Compile>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.IO;
3+
using System.Text;
4+
5+
using OriginalScriptSource = Jurassic.ScriptSource;
6+
7+
using CoreStrings = JavaScriptEngineSwitcher.Core.Resources.Strings;
8+
9+
namespace JavaScriptEngineSwitcher.Jurassic
10+
{
11+
/// <summary>
12+
/// Represents a JS-file
13+
/// </summary>
14+
internal sealed class FileScriptSource : OriginalScriptSource
15+
{
16+
/// <summary>
17+
/// The document name
18+
/// </summary>
19+
private readonly string _documentName;
20+
21+
/// <summary>
22+
/// The path to the JS-file
23+
/// </summary>
24+
private readonly string _path;
25+
26+
/// <summary>
27+
/// The text encoding
28+
/// </summary>
29+
private readonly Encoding _encoding;
30+
31+
/// <summary>
32+
/// Gets a document name
33+
/// </summary>
34+
public override string Path
35+
{
36+
get { return _documentName; }
37+
}
38+
39+
40+
/// <summary>
41+
/// Constructs a instance of <see cref="FileScriptSource"/>
42+
/// </summary>
43+
/// <param name="documentName">The document name</param>
44+
/// <param name="path">The path to the JS-file</param>
45+
/// <param name="encoding">The text encoding</param>
46+
public FileScriptSource(string documentName, string path, Encoding encoding = null)
47+
{
48+
if (documentName == null)
49+
{
50+
throw new ArgumentNullException(
51+
"documentName", string.Format(CoreStrings.Common_ArgumentIsNull, "documentName"));
52+
}
53+
54+
if (path == null)
55+
{
56+
throw new ArgumentNullException(
57+
"path", string.Format(CoreStrings.Common_ArgumentIsNull, "path"));
58+
}
59+
60+
if (string.IsNullOrWhiteSpace(documentName))
61+
{
62+
throw new ArgumentException(
63+
string.Format(CoreStrings.Common_ArgumentIsEmpty, "documentName"), "documentName");
64+
}
65+
66+
if (string.IsNullOrWhiteSpace(path))
67+
{
68+
throw new ArgumentException(
69+
string.Format(CoreStrings.Common_ArgumentIsEmpty, "path"), "path");
70+
}
71+
72+
_documentName = documentName;
73+
_path = path;
74+
_encoding = encoding ?? Encoding.UTF8;
75+
}
76+
77+
78+
/// <summary>
79+
/// Gets a reader that can be used to read the source code from JS-file
80+
/// </summary>
81+
/// <returns>A reader that can be used to read the source code from JS-file,
82+
/// positioned at the start of the source code</returns>
83+
public override TextReader GetReader()
84+
{
85+
return new StreamReader(_path, _encoding, true);
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)