Skip to content

Commit 5b29ab6

Browse files
build: add ts support in core modules
1 parent bd8522a commit 5b29ab6

5 files changed

Lines changed: 535 additions & 21 deletions

File tree

configure.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1737,7 +1737,8 @@ def gcc_version_ge(version_checked):
17371737
return True
17381738

17391739
def configure_node_lib_files(o):
1740-
o['variables']['node_library_files'] = SearchFiles('lib', 'js')
1740+
o['variables']['node_library_files'] = SearchFiles('lib', 'js') + \
1741+
SearchFiles('lib', 'ts')
17411742

17421743
def configure_node_cctest_sources(o):
17431744
o['variables']['node_cctest_sources'] = [ 'src/node_snapshot_stub.cc' ] + \

node.gyp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,12 +1552,25 @@
15521552
'target_name': 'node_js2c',
15531553
'type': 'executable',
15541554
'toolsets': ['host'],
1555+
'dependencies': [
1556+
'tools/v8_gypfiles/v8.gyp:v8_base_without_compiler',
1557+
'tools/v8_gypfiles/v8.gyp:v8_init',
1558+
'tools/v8_gypfiles/v8.gyp:v8_libbase',
1559+
'tools/v8_gypfiles/v8.gyp:v8_libplatform',
1560+
'tools/v8_gypfiles/v8.gyp:v8_maybe_icu',
1561+
'tools/v8_gypfiles/v8.gyp:fp16',
1562+
'tools/v8_gypfiles/abseil.gyp:abseil',
1563+
],
15551564
'include_dirs': [
1565+
'deps/v8',
1566+
'deps/v8/include',
15561567
'tools',
15571568
'src',
15581569
],
15591570
'sources': [
15601571
'tools/js2c.cc',
1572+
'tools/typescript_transpiler.cc',
1573+
'tools/typescript_transpiler.h',
15611574
'tools/executable_wrapper.h',
15621575
'src/embedded_data.h',
15631576
'src/embedded_data.cc',

tools/js2c.cc

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "embedded_data.h"
1414
#include "executable_wrapper.h"
1515
#include "simdutf.h"
16+
#include "typescript_transpiler.h"
1617
#include "uv.h"
1718

1819
#if defined(_WIN32)
@@ -131,13 +132,14 @@ bool SearchFiles(const std::string& dir,
131132

132133
constexpr std::string_view kMjsSuffix = ".mjs";
133134
constexpr std::string_view kJsSuffix = ".js";
135+
constexpr std::string_view kTsSuffix = ".ts";
134136
constexpr std::string_view kGypiSuffix = ".gypi";
135137
constexpr std::string_view depsPrefix = "deps/";
136138
constexpr std::string_view libPrefix = "lib/";
137139

138140
constexpr std::string_view HasAllowedExtensions(
139141
const std::string_view filename) {
140-
for (const auto& ext : {kGypiSuffix, kJsSuffix, kMjsSuffix}) {
142+
for (const auto& ext : {kGypiSuffix, kJsSuffix, kMjsSuffix, kTsSuffix}) {
141143
if (filename.ends_with(ext)) {
142144
return ext;
143145
}
@@ -329,11 +331,13 @@ std::string GetFileId(const std::string& filename) {
329331
size_t end = filename.size();
330332
size_t start = 0;
331333
std::string prefix;
332-
// Strip .mjs and .js suffix
334+
// Strip .mjs, .js and .ts suffix
333335
if (filename.ends_with(kMjsSuffix)) {
334336
end -= kMjsSuffix.size();
335337
} else if (filename.ends_with(kJsSuffix)) {
336338
end -= kJsSuffix.size();
339+
} else if (filename.ends_with(kTsSuffix)) {
340+
end -= kTsSuffix.size();
337341
}
338342

339343
// deps/acorn/acorn/dist/acorn.js -> internal/deps/acorn/acorn/dist/acorn
@@ -670,6 +674,7 @@ Fragment GetDefinition(const std::string& var, const std::vector<char>& code) {
670674
}
671675

672676
int AddModule(const std::string& filename,
677+
TypeScriptTranspiler* transpiler,
673678
Fragments* definitions,
674679
Fragments* initializers,
675680
Fragments* registrations) {
@@ -684,6 +689,20 @@ int AddModule(const std::string& filename,
684689
if (error != 0) {
685690
return error;
686691
}
692+
693+
if (filename.ends_with(kTsSuffix)) {
694+
std::vector<char> transpiled;
695+
std::string source(code.begin(), code.end());
696+
if (transpiler->Strip(source, filename, &transpiled) != 0) {
697+
fprintf(stderr,
698+
"Failed to transpile TypeScript file %s: %s\n",
699+
filename.c_str(),
700+
transpiler->LastError().c_str());
701+
return 1;
702+
}
703+
code = std::move(transpiled);
704+
}
705+
687706
std::string file_id = GetFileId(filename);
688707
std::string var = GetVariableName(file_id);
689708

@@ -826,23 +845,43 @@ int AddGypi(const std::string& var,
826845

827846
int JS2C(const FileList& js_files,
828847
const FileList& mjs_files,
848+
const FileList& ts_files,
829849
const std::string& config,
850+
const char* argv0,
830851
const std::string& dest) {
852+
TypeScriptTranspiler transpiler;
831853
Fragments definitions;
832-
definitions.reserve(js_files.size() + mjs_files.size() + 1);
854+
definitions.reserve(js_files.size() + mjs_files.size() + ts_files.size() + 1);
833855
Fragments initializers;
834-
initializers.reserve(js_files.size() + mjs_files.size());
856+
initializers.reserve(js_files.size() + mjs_files.size() + ts_files.size());
835857
Fragments registrations;
836-
registrations.reserve(js_files.size() + mjs_files.size() + 1);
858+
registrations.reserve(js_files.size() + mjs_files.size() + ts_files.size() +
859+
1);
860+
861+
if (!ts_files.empty() && transpiler.Initialize(argv0) != 0) {
862+
fprintf(stderr,
863+
"Failed to initialize TypeScript transpiler: %s\n",
864+
transpiler.LastError().c_str());
865+
return 1;
866+
}
837867

838868
for (const auto& filename : js_files) {
839-
int r = AddModule(filename, &definitions, &initializers, &registrations);
869+
int r = AddModule(
870+
filename, &transpiler, &definitions, &initializers, &registrations);
840871
if (r != 0) {
841872
return r;
842873
}
843874
}
844875
for (const auto& filename : mjs_files) {
845-
int r = AddModule(filename, &definitions, &initializers, &registrations);
876+
int r = AddModule(
877+
filename, &transpiler, &definitions, &initializers, &registrations);
878+
if (r != 0) {
879+
return r;
880+
}
881+
}
882+
for (const auto& filename : ts_files) {
883+
int r = AddModule(
884+
filename, &transpiler, &definitions, &initializers, &registrations);
846885
if (r != 0) {
847886
return r;
848887
}
@@ -910,7 +949,8 @@ int Main(int argc, char* argv[]) {
910949
const std::string& file = args[i];
911950
if (IsDirectory(file, &error)) {
912951
if (!SearchFiles(file, &file_map, kJsSuffix) ||
913-
!SearchFiles(file, &file_map, kMjsSuffix)) {
952+
!SearchFiles(file, &file_map, kMjsSuffix) ||
953+
!SearchFiles(file, &file_map, kTsSuffix)) {
914954
return 1;
915955
}
916956
} else if (error != 0) {
@@ -927,8 +967,6 @@ int Main(int argc, char* argv[]) {
927967
}
928968
}
929969

930-
// Should have exactly 3 types: `.js`, `.mjs` and `.gypi`.
931-
assert(file_map.size() == 3);
932970
auto gypi_it = file_map.find(".gypi");
933971
// Currently config.gypi is the only `.gypi` file allowed
934972
if (gypi_it == file_map.end() || gypi_it->second.size() != 1 ||
@@ -940,19 +978,37 @@ int Main(int argc, char* argv[]) {
940978
}
941979
auto js_it = file_map.find(".js");
942980
auto mjs_it = file_map.find(".mjs");
943-
assert(js_it != file_map.end() && mjs_it != file_map.end());
944-
945-
auto it = std::find(mjs_it->second.begin(),
946-
mjs_it->second.end(),
947-
"lib/eslint.config_partial.mjs");
948-
if (it != mjs_it->second.end()) {
949-
mjs_it->second.erase(it);
981+
auto ts_it = file_map.find(".ts");
982+
if (mjs_it != file_map.end()) {
983+
auto it = std::find(mjs_it->second.begin(),
984+
mjs_it->second.end(),
985+
"lib/eslint.config_partial.mjs");
986+
if (it != mjs_it->second.end()) {
987+
mjs_it->second.erase(it);
988+
}
950989
}
951990

952-
std::sort(js_it->second.begin(), js_it->second.end());
953-
std::sort(mjs_it->second.begin(), mjs_it->second.end());
991+
if (js_it != file_map.end()) {
992+
std::sort(js_it->second.begin(), js_it->second.end());
993+
}
994+
if (mjs_it != file_map.end()) {
995+
std::sort(mjs_it->second.begin(), mjs_it->second.end());
996+
}
997+
if (ts_it != file_map.end()) {
998+
std::sort(ts_it->second.begin(), ts_it->second.end());
999+
}
9541000

955-
return JS2C(js_it->second, mjs_it->second, gypi_it->second[0], output);
1001+
static const FileList empty_list;
1002+
const FileList& js_files =
1003+
js_it == file_map.end() ? empty_list : js_it->second;
1004+
const FileList& mjs_files =
1005+
mjs_it == file_map.end() ? empty_list : mjs_it->second;
1006+
return JS2C(js_files,
1007+
mjs_files,
1008+
ts_it == file_map.end() ? empty_list : ts_it->second,
1009+
gypi_it->second[0],
1010+
argv[0],
1011+
output);
9561012
}
9571013
} // namespace js2c
9581014
} // namespace node

0 commit comments

Comments
 (0)