Skip to content

Commit 7993912

Browse files
committed
Add ability to return a source map from JsxTransformer.
1 parent b710d1a commit 7993912

File tree

7 files changed

+175
-5
lines changed

7 files changed

+175
-5
lines changed

src/React/IJsxTransformer.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ public interface IJsxTransformer
1818
/// Transforms a JSX file. Results of the JSX to JavaScript transformation are cached.
1919
/// </summary>
2020
/// <param name="filename">Name of the file to load</param>
21-
/// <param name="useHarmony"><c>true</c> if support for es6 syntax should be rewritten.</param>
21+
/// <param name="useHarmony"><c>true</c> if support for ES6 syntax should be enabled</param>
2222
/// <returns>JavaScript</returns>
2323
string TransformJsxFile(string filename, bool? useHarmony = null);
2424

@@ -27,16 +27,25 @@ public interface IJsxTransformer
2727
/// <see cref="TransformJsxFile"/> if loading from a file since this will cache the result.
2828
/// </summary>
2929
/// <param name="input">JSX</param>
30-
/// <param name="useHarmony"><c>true</c> if support for es6 syntax should be rewritten.</param>
30+
/// <param name="useHarmony"><c>true</c> if support for ES6 syntax should be enabled</param>
3131
/// <returns>JavaScript</returns>
3232
string TransformJsx(string input, bool? useHarmony = null);
33+
34+
/// <summary>
35+
/// Transforms JSX to regular JavaScript and also returns a source map to map the compiled
36+
/// source to the original version. The result is not cached.
37+
/// </summary>
38+
/// <param name="input">JSX</param>
39+
/// <param name="useHarmony"><c>true</c> if support for ES6 syntax should be enabled</param>
40+
/// <returns>JavaScript and source map</returns>
41+
JavaScriptWithSourceMap TransformJsxWithSourceMap(string input, bool? useHarmony);
3342

3443
/// <summary>
3544
/// Transforms a JSX file to JavaScript, and saves the result into a ".generated.js" file
3645
/// alongside the original file.
3746
/// </summary>
3847
/// <param name="filename">Name of the file to load</param>
39-
/// <param name="useHarmony"><c>true</c> if support for es6 syntax should be rewritten.</param>
48+
/// <param name="useHarmony"><c>true</c> if support for ES6 syntax should be enabled</param>
4049
/// <returns>File contents</returns>
4150
string TransformAndSaveJsxFile(string filename, bool? useHarmony = null);
4251

src/React/JavaScriptWithSourceMap.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright (c) 2014, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
using System;
11+
12+
namespace React
13+
{
14+
/// <summary>
15+
/// Represents the result of a JSX to JavaScript transformation along with its
16+
/// corresponding source map.
17+
/// </summary>
18+
[Serializable]
19+
public class JavaScriptWithSourceMap
20+
{
21+
/// <summary>
22+
/// The transformed result
23+
/// </summary>
24+
public string Code { get; set; }
25+
26+
/// <summary>
27+
/// The source map for this code
28+
/// </summary>
29+
public SourceMap SourceMap { get; set; }
30+
}
31+
}

src/React/JsxTransformer.cs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public string TransformJsx(string input, bool? useHarmony = null)
147147
var output = _environment.ExecuteWithLargerStackIfRequired<string>(
148148
"ReactNET_transform",
149149
input,
150-
useHarmony.HasValue ? useHarmony.Value : _config.UseHarmony
150+
useHarmony ?? _config.UseHarmony
151151
);
152152
return output;
153153
}
@@ -157,6 +157,30 @@ public string TransformJsx(string input, bool? useHarmony = null)
157157
}
158158
}
159159

160+
/// <summary>
161+
/// Transforms JSX to regular JavaScript and also returns a source map to map the compiled
162+
/// source to the original version. The result is not cached.
163+
/// </summary>
164+
/// <param name="input">JSX</param>
165+
/// <param name="useHarmony"><c>true</c> if support for ES6 syntax should be enabled</param>
166+
/// <returns>JavaScript and source map</returns>
167+
public JavaScriptWithSourceMap TransformJsxWithSourceMap(string input, bool? useHarmony)
168+
{
169+
EnsureJsxTransformerSupported();
170+
try
171+
{
172+
return _environment.ExecuteWithLargerStackIfRequired<JavaScriptWithSourceMap>(
173+
"ReactNET_transform_sourcemap",
174+
input,
175+
useHarmony ?? _config.UseHarmony
176+
);
177+
}
178+
catch (Exception ex)
179+
{
180+
throw new JsxException(ex.Message, ex);
181+
}
182+
}
183+
160184
/// <summary>
161185
/// Gets the header prepended to JSX transformed files. Contains a hash that is used to
162186
/// validate the cache.

src/React/React.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@
8585
<Compile Include="AssemblyRegistration.cs" />
8686
<Compile Include="Exceptions\ReactScriptLoadException.cs" />
8787
<Compile Include="Exceptions\ReactServerRenderingException.cs" />
88+
<Compile Include="JavaScriptWithSourceMap.cs" />
89+
<Compile Include="SourceMap.cs" />
8890
<Compile Include="SystemEnvironmentUtils.cs" />
8991
<Compile Include="Exceptions\JsxUnsupportedEngineException.cs" />
9092
<Compile Include="Exceptions\ReactConfigurationException.cs" />

src/React/ReactEnvironment.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
using System.Text;
1515
using System.Threading;
1616
using JavaScriptEngineSwitcher.Core;
17+
using JavaScriptEngineSwitcher.Core.Helpers;
18+
using Newtonsoft.Json;
1719
using React.Exceptions;
1820

1921
namespace React
@@ -231,7 +233,26 @@ public T Execute<T>(string function, params object[] args)
231233
{
232234
try
233235
{
234-
return Engine.CallFunction<T>(function, args);
236+
if (ValidationHelpers.IsSupportedType(typeof (T)))
237+
{
238+
// Type is supported directly (ie. a scalar type like string/int/bool)
239+
// Just execute the function directly.
240+
return Engine.CallFunction<T>(function, args);
241+
}
242+
// The type is not a scalar type. Assume the function will return its result as
243+
// JSON.
244+
var resultJson = Engine.CallFunction<string>(function, args);
245+
try
246+
{
247+
return JsonConvert.DeserializeObject<T>(resultJson);
248+
}
249+
catch (JsonReaderException ex)
250+
{
251+
throw new ReactException(string.Format(
252+
"{0} did not return valid JSON: {1}.\n\n{2}",
253+
function, ex.Message, resultJson
254+
));
255+
}
235256
}
236257
catch (JsRuntimeException ex)
237258
{

src/React/Resources/shims.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,26 @@ function ReactNET_transform(input, harmony) {
2525
} catch (ex) {
2626
throw new Error(ex.message + " (at line " + ex.lineNumber + " column " + ex.column + ")");
2727
}
28+
}
29+
30+
function ReactNET_transform_sourcemap(input, harmony) {
31+
try {
32+
var result = global.JSXTransformer.transform(input, {
33+
harmony: !!harmony,
34+
sourceMap: true
35+
});
36+
if (!result.sourceMap) {
37+
return JSON.stringify({
38+
code: result.code,
39+
sourceMap: null
40+
});
41+
}
42+
43+
return JSON.stringify({
44+
code: result.code,
45+
sourceMap: result.sourceMap.toJSON()
46+
});
47+
} catch (ex) {
48+
throw new Error(ex.message + " (at line " + ex.lineNumber + " column " + ex.column + ")");
49+
}
2850
}

src/React/SourceMap.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2014, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
using System;
11+
using System.Collections.Generic;
12+
13+
namespace React
14+
{
15+
/// <summary>
16+
/// Represents the data contained in a source map
17+
/// </summary>
18+
[Serializable]
19+
public class SourceMap
20+
{
21+
/// <summary>
22+
/// Version number of the source map spec used to build this source map. Expected
23+
/// to be version 3.
24+
/// </summary>
25+
public int Version { get; set; }
26+
27+
/// <summary>
28+
/// An optional name of the generated code that this source map is associated with.
29+
/// </summary>
30+
public string File { get; set; }
31+
32+
/// <summary>
33+
/// An optional source root, useful for relocating source files on a server or
34+
/// removing repeated values in the <see cref="Sources"/> entry. This value is
35+
/// prepended to the individual entries in the <see cref="Sources"/> field.
36+
/// </summary>
37+
public string SourceRoot { get; set; }
38+
39+
/// <summary>
40+
/// A list of original sources used by the <see cref="Mappings"/> entry.
41+
/// </summary>
42+
public IList<string> Sources { get; set; }
43+
44+
/// <summary>
45+
/// An optional list of source content, useful when the <see cref="Sources"/> can't
46+
/// be hosted. The contents are listed in the same order as the <see cref="Sources"/>.
47+
/// <c>null</c> may be used if some original sources should be retrieved by name.
48+
/// </summary>
49+
public IList<string> SourcesContent { get; set; }
50+
51+
/// <summary>
52+
/// A list of symbol names used by the <see cref="Mappings"/> entry.
53+
/// </summary>
54+
public IList<string> Names { get; set; }
55+
56+
/// <summary>
57+
/// A string with the mapping data encoded in base 64 VLQ.
58+
/// </summary>
59+
public string Mappings { get; set; }
60+
}
61+
}

0 commit comments

Comments
 (0)