@@ -42,6 +42,21 @@ const EOL = process.platform === "win32" ? "\r\n" : "\n";
4242const SEP = process.platform === "win32" ? "\\" : "/";
4343const binaryen = global.binaryen || (global.binaryen = require("binaryen"));
4444
45+ // Sets up an extension with its definition counterpart and relevant regexes.
46+ function setupExtension(extension) {
47+ if (!extension.startsWith(".")) extension = "." + extension;
48+ return {
49+ ext: extension,
50+ ext_d: ".d" + extension,
51+ re: new RegExp("\\" + extension + "$"),
52+ re_d: new RegExp("\\.d\\" + extension + "$"),
53+ re_except_d: new RegExp("^(?!.*\\.d\\" + extension + "$).*\\" + extension + "$"),
54+ re_index: new RegExp("(?:^|[\\\\\\/])index\\" + extension + "$")
55+ };
56+ }
57+
58+ const defaultExtension = setupExtension(".ts");
59+
4560// Proxy Binaryen's ready event
4661Object.defineProperty(exports, "ready", {
4762 get: function() { return binaryen.ready; }
@@ -109,23 +124,23 @@ exports.defaultShrinkLevel = 1;
109124exports.libraryFiles = exports.isBundle ? BUNDLE_LIBRARY : (() => { // set up if not a bundle
110125 const libDir = path.join(__dirname, "..", "std", "assembly");
111126 const bundled = {};
112- find.files(libDir, find.TS_EXCEPT_DTS )
113- .forEach(file => bundled[file.replace(/\.ts$/ , "")] = fs.readFileSync(path.join(libDir, file), "utf8" ));
127+ find.files(libDir, defaultExtension.re_except_d )
128+ .forEach(file => bundled[file.replace(defaultExtension.re , "")] = fs.readFileSync(path.join(libDir, file), "utf8" ));
114129 return bundled;
115130})();
116131
117132/** Bundled definition files. */
118133exports.definitionFiles = exports.isBundle ? BUNDLE_DEFINITIONS : (() => { // set up if not a bundle
119134 const stdDir = path.join(__dirname, "..", "std");
120135 return {
121- "assembly": fs.readFileSync(path.join(stdDir, "assembly", "index.d.ts" ), "utf8"),
122- "portable": fs.readFileSync(path.join(stdDir, "portable", "index.d.ts" ), "utf8")
136+ "assembly": fs.readFileSync(path.join(stdDir, "assembly", "index" + defaultExtension.ext_d ), "utf8"),
137+ "portable": fs.readFileSync(path.join(stdDir, "portable", "index" + defaultExtension.ext_d ), "utf8")
123138 };
124139})();
125140
126141/** Convenience function that parses and compiles source strings directly. */
127142exports.compileString = (sources, options) => {
128- if (typeof sources === "string") sources = { "input.ts" : sources };
143+ if (typeof sources === "string") sources = { [ "input" + defaultExtension.ext] : sources };
129144 const output = Object.create({
130145 stdout: createMemoryStream(),
131146 stderr: createMemoryStream()
@@ -169,6 +184,7 @@ exports.main = function main(argv, options, callback) {
169184 const writeFile = options.writeFile || writeFileNode;
170185 const listFiles = options.listFiles || listFilesNode;
171186 const stats = options.stats || createStats();
187+ let extension = defaultExtension;
172188
173189 // Output must be specified if not present in the environment
174190 if (!stdout) throw Error("'options.stdout' must be specified");
@@ -213,6 +229,15 @@ exports.main = function main(argv, options, callback) {
213229 return callback(null);
214230 }
215231
232+ // Use another extension if requested
233+ if (typeof args.extension === "string") {
234+ if (/^\.?[0-9a-zA-Z]{1,14}$/.test(args.extension)) {
235+ extension = setupExtension(args.extension);
236+ } else {
237+ return callback(Error("Invalid extension: " + args.extension));
238+ }
239+ }
240+
216241 // Print the help message if requested or no source files are provided
217242 if (args.help || !argv.length) {
218243 var out = args.help ? stdout : stderr;
@@ -222,9 +247,9 @@ exports.main = function main(argv, options, callback) {
222247 " " + color.cyan("asc") + " [entryFile ...] [options]",
223248 "",
224249 color.white("EXAMPLES"),
225- " " + color.cyan("asc") + " hello.ts" ,
226- " " + color.cyan("asc") + " hello.ts -b hello.wasm -t hello.wat",
227- " " + color.cyan("asc") + " hello1.ts hello2.ts -b -O > hello.wasm",
250+ " " + color.cyan("asc") + " hello" + extension.ext ,
251+ " " + color.cyan("asc") + " hello" + extension.ext + " -b hello.wasm -t hello.wat",
252+ " " + color.cyan("asc") + " hello1" + extension.ext + " hello2" + extension.ext + " -b -O > hello.wasm",
228253 "",
229254 color.white("OPTIONS"),
230255 ].concat(
@@ -319,7 +344,7 @@ exports.main = function main(argv, options, callback) {
319344 let transformArgs = args.transform;
320345 for (let i = 0, k = transformArgs.length; i < k; ++i) {
321346 let filename = transformArgs[i].trim();
322- if (!tsNodeRegistered && filename.endsWith(' .ts' )) {
347+ if (!tsNodeRegistered && filename.endsWith(" .ts" )) { // ts-node requires .ts specifically
323348 require("ts-node").register({ transpileOnly: true, skipProject: true, compilerOptions: { target: "ES2016" } });
324349 tsNodeRegistered = true;
325350 }
@@ -363,7 +388,7 @@ exports.main = function main(argv, options, callback) {
363388 if (libPath.indexOf("/") >= 0) return; // in sub-directory: imported on demand
364389 stats.parseCount++;
365390 stats.parseTime += measure(() => {
366- assemblyscript.parse(program, exports.libraryFiles[libPath], exports.libraryPrefix + libPath + ".ts" , false);
391+ assemblyscript.parse(program, exports.libraryFiles[libPath], exports.libraryPrefix + libPath + extension.ext , false);
367392 });
368393 });
369394 const customLibDirs = [];
@@ -374,7 +399,7 @@ exports.main = function main(argv, options, callback) {
374399 for (let i = 0, k = customLibDirs.length; i < k; ++i) { // custom
375400 let libDir = customLibDirs[i];
376401 let libFiles;
377- if (libDir.endsWith(".ts" )) {
402+ if (libDir.endsWith(extension.ext )) {
378403 libFiles = [ path.basename(libDir) ];
379404 libDir = path.dirname(libDir);
380405 } else {
@@ -385,7 +410,7 @@ exports.main = function main(argv, options, callback) {
385410 let libText = readFile(libPath, libDir);
386411 if (libText === null) return callback(Error("Library file '" + libPath + "' not found."));
387412 stats.parseCount++;
388- exports.libraryFiles[libPath.replace(/\.ts$/ , "")] = libText;
413+ exports.libraryFiles[libPath.replace(extension.re , "")] = libText;
389414 stats.parseTime += measure(() => {
390415 assemblyscript.parse(program, libText, exports.libraryPrefix + libPath, false);
391416 });
@@ -406,13 +431,13 @@ exports.main = function main(argv, options, callback) {
406431 const libraryPrefix = exports.libraryPrefix;
407432 const libraryFiles = exports.libraryFiles;
408433
409- // Try file.ts , file/index.ts , file.d.ts
434+ // Try file.ext , file/index.ext , file.d.ext
410435 if (!internalPath.startsWith(libraryPrefix)) {
411- if ((sourceText = readFile(sourcePath = internalPath + ".ts" , baseDir)) == null) {
412- if ((sourceText = readFile(sourcePath = internalPath + "/index.ts" , baseDir)) == null) {
413- // portable d.ts : uses the .js file next to it in JS or becomes an import in Wasm
414- sourcePath = internalPath + ".ts" ;
415- sourceText = readFile(internalPath + ".d.ts" , baseDir);
436+ if ((sourceText = readFile(sourcePath = internalPath + extension.ext , baseDir)) == null) {
437+ if ((sourceText = readFile(sourcePath = internalPath + "/index" + extension.ext , baseDir)) == null) {
438+ // portable d.ext : uses the .js file next to it in JS or becomes an import in Wasm
439+ sourcePath = internalPath + extension.ext ;
440+ sourceText = readFile(internalPath + extension.ext_d , baseDir);
416441 }
417442 }
418443
@@ -422,18 +447,18 @@ exports.main = function main(argv, options, callback) {
422447 const indexName = plainName + "/index";
423448 if (libraryFiles.hasOwnProperty(plainName)) {
424449 sourceText = libraryFiles[plainName];
425- sourcePath = libraryPrefix + plainName + ".ts" ;
450+ sourcePath = libraryPrefix + plainName + extension.ext ;
426451 } else if (libraryFiles.hasOwnProperty(indexName)) {
427452 sourceText = libraryFiles[indexName];
428- sourcePath = libraryPrefix + indexName + ".ts" ;
453+ sourcePath = libraryPrefix + indexName + extension.ext ;
429454 } else { // custom lib dirs
430455 for (const libDir of customLibDirs) {
431- if ((sourceText = readFile(plainName + ".ts" , libDir)) != null) {
432- sourcePath = libraryPrefix + plainName + ".ts" ;
456+ if ((sourceText = readFile(plainName + extension.ext , libDir)) != null) {
457+ sourcePath = libraryPrefix + plainName + extension.ext ;
433458 break;
434459 } else {
435- if ((sourceText = readFile(indexName + ".ts" , libDir)) != null) {
436- sourcePath = libraryPrefix + indexName + ".ts" ;
460+ if ((sourceText = readFile(indexName + extension.ext , libDir)) != null) {
461+ sourcePath = libraryPrefix + indexName + extension.ext ;
437462 break;
438463 }
439464 }
@@ -463,25 +488,25 @@ exports.main = function main(argv, options, callback) {
463488 try {
464489 let json = JSON.parse(jsonText);
465490 if (typeof json.ascMain === "string") {
466- mainPath = json.ascMain.replace(/[\/\\]index\.ts$/ , "");
491+ mainPath = json.ascMain.replace(extension.re_index , "");
467492 packageMains.set(packageName, mainPath);
468493 }
469494 } catch (e) { }
470495 }
471496 }
472497 const mainDir = path.join(currentPath, packageName, mainPath);
473498 const plainName = filePath;
474- if ((sourceText = readFile(path.join(mainDir, plainName + ".ts" ), baseDir)) != null) {
475- sourcePath = libraryPrefix + packageName + "/" + plainName + ".ts" ;
476- packageBases.set(sourcePath.replace(/\.ts$/ , ""), path.join(currentPath, packageName));
477- if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + ".ts" ) + EOL);
499+ if ((sourceText = readFile(path.join(mainDir, plainName + extension.ext ), baseDir)) != null) {
500+ sourcePath = libraryPrefix + packageName + "/" + plainName + extension.ext ;
501+ packageBases.set(sourcePath.replace(extension.re , ""), path.join(currentPath, packageName));
502+ if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, plainName + extension.ext ) + EOL);
478503 break;
479504 } else if (!isPackageRoot) {
480505 const indexName = filePath + "/index";
481- if ((sourceText = readFile(path.join(mainDir, indexName + ".ts" ), baseDir)) !== null) {
482- sourcePath = libraryPrefix + packageName + "/" + indexName + ".ts" ;
483- packageBases.set(sourcePath.replace(/\.ts$/ , ""), path.join(currentPath, packageName));
484- if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + ".ts" ) + EOL);
506+ if ((sourceText = readFile(path.join(mainDir, indexName + extension.ext ), baseDir)) !== null) {
507+ sourcePath = libraryPrefix + packageName + "/" + indexName + extension.ext ;
508+ packageBases.set(sourcePath.replace(extension.re , ""), path.join(currentPath, packageName));
509+ if (args.traceResolution) stderr.write(" -> " + path.join(mainDir, indexName + extension.ext ) + EOL);
485510 break;
486511 }
487512 }
@@ -519,33 +544,34 @@ exports.main = function main(argv, options, callback) {
519544 let runtimeText = exports.libraryFiles[runtimePath];
520545 if (runtimeText == null) {
521546 runtimePath = runtimeName;
522- runtimeText = readFile(runtimePath + ".ts" , baseDir);
547+ runtimeText = readFile(runtimePath + extension.ext , baseDir);
523548 if (runtimeText == null) return callback(Error("Runtime '" + runtimeName + "' not found."));
524549 } else {
525550 runtimePath = "~lib/" + runtimePath;
526551 }
527552 stats.parseCount++;
528553 stats.parseTime += measure(() => {
529- assemblyscript.parse(program, runtimeText, runtimePath, true);
554+ assemblyscript.parse(program, runtimeText, runtimePath + extension.ext , true);
530555 });
531556 }
532557
533558 // Include entry files
534559 for (let i = 0, k = argv.length; i < k; ++i) {
535560 const filename = argv[i];
536561
537- let sourcePath = String(filename).replace(/\\/g, "/").replace(/(\.ts|\/)$/, "");
562+ let sourcePath = String(filename).replace(/\\/g, "/").replace(extension.re, "").replace(/[\\\/]$/, "");
563+
538564 // Setting the path to relative path
539565 sourcePath = path.isAbsolute(sourcePath) ? path.relative(baseDir, sourcePath) : sourcePath;
540566
541- // Try entryPath.ts , then entryPath/index.ts
542- let sourceText = readFile(sourcePath + ".ts" , baseDir);
567+ // Try entryPath.ext , then entryPath/index.ext
568+ let sourceText = readFile(sourcePath + extension.ext , baseDir);
543569 if (sourceText == null) {
544- sourceText = readFile(sourcePath + "/index.ts" , baseDir);
545- if (sourceText == null) return callback(Error("Entry file '" + sourcePath + ".ts ' not found."));
546- sourcePath += "/index.ts" ;
570+ sourceText = readFile(sourcePath + "/index" + extension.ext , baseDir);
571+ if (sourceText == null) return callback(Error("Entry file '" + sourcePath + extension.ext + " ' not found."));
572+ sourcePath += "/index" + extension.ext ;
547573 } else {
548- sourcePath += ".ts" ;
574+ sourcePath += extension.ext ;
549575 }
550576
551577 stats.parseCount++;
@@ -741,7 +767,7 @@ exports.main = function main(argv, options, callback) {
741767 map.sourceRoot = "./" + basename;
742768 let contents = [];
743769 map.sources.forEach((name, index) => {
744- let text = assemblyscript.getSource(program, name.replace(/\.ts$/ , ""));
770+ let text = assemblyscript.getSource(program, name.replace(extension.re , ""));
745771 if (text == null) return callback(Error("Source of file '" + name + "' not found."));
746772 contents[index] = text;
747773 });
@@ -882,7 +908,7 @@ exports.main = function main(argv, options, callback) {
882908 var files;
883909 try {
884910 stats.readTime += measure(() => {
885- files = fs.readdirSync(path.join(baseDir, dirname)).filter(file => /^(?!.*\.d\.ts$).*\.ts$/. test(file));
911+ files = fs.readdirSync(path.join(baseDir, dirname)).filter(file => extension.re_except_d. test(file))
886912 });
887913 return files;
888914 } catch (e) {
0 commit comments