diff --git a/Jakefile.js b/Jakefile.js index 5ae4ab6e497d1..e6b64789a5f67 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -5,7 +5,6 @@ var os = require("os"); var path = require("path"); var child_process = require("child_process"); var Linter = require("tslint"); -var readline = require("readline"); // Variables var compilerDirectory = "src/compiler/"; @@ -54,7 +53,6 @@ var compilerSources = [ "transformer.ts", "sourcemap.ts", "comments.ts", - "printer.ts", "declarationEmitter.ts", "emitter.ts", "program.ts", @@ -87,7 +85,6 @@ var servicesSources = [ "transformer.ts", "sourcemap.ts", "comments.ts", - "printer.ts", "declarationEmitter.ts", "emitter.ts", "program.ts", @@ -193,17 +190,6 @@ var harnessSources = harnessCoreSources.concat([ return path.join(serverDirectory, f); })); -var librarySourceMap = [ - { target: "lib.core.d.ts", sources: ["header.d.ts", "core.d.ts"] }, - { target: "lib.dom.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "dom.generated.d.ts"] }, - { target: "lib.webworker.d.ts", sources: ["importcore.d.ts", "intl.d.ts", "webworker.generated.d.ts"] }, - { target: "lib.scriptHost.d.ts", sources: ["importcore.d.ts", "scriptHost.d.ts"] }, - { target: "lib.d.ts", sources: ["header.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }, - { target: "lib.core.es6.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts"] }, - { target: "lib.es6.d.ts", sources: ["header.d.ts", "es6.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] }, - { target: "lib.core.es7.d.ts", sources: ["header.d.ts", "core.d.ts", "es6.d.ts", "es7.d.ts"] }, - { target: "lib.es7.d.ts", sources: ["header.d.ts", "es6.d.ts", "es7.d.ts", "core.d.ts", "intl.d.ts", "dom.generated.d.ts", "dom.es6.d.ts", "webworker.importscripts.d.ts", "scriptHost.d.ts"] } -]; var es2015LibrarySources = [ "es2015.core.d.ts", "es2015.collection.d.ts", @@ -314,6 +300,10 @@ var builtLocalCompiler = path.join(builtLocalDirectory, compilerFilename); */ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts, callback) { file(outFile, prereqs, function() { + if (process.env.USE_TRANSFORMS === "false") { + useBuiltCompiler = false; + } + var compilerPath = useBuiltCompiler ? builtLocalCompiler : LKGCompiler; var options = "--noImplicitAny --noEmitOnError --pretty"; opts = opts || {}; @@ -357,10 +347,6 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts options += " --stripInternal"; } - if (useBuiltCompiler && !environmentVariableIsDisabled("USE_TRANSFORMS")) { - console.warn("\u001b[93mwarning: 'USE_TRANSFORMS' environment variable is not set to 'false'. Experimental transforms will be enabled by default.\u001b[0m"); - } - var cmd = host + " " + compilerPath + " " + options + " "; cmd = cmd + sources.join(" "); console.log(cmd + "\n"); @@ -723,33 +709,16 @@ function cleanTestDirs() { } // used to pass data from jake command line directly to run.js -function writeTestConfigFile(tests, light, taskConfigFolder, workerCount, stackTraceLimit) { - var testConfig; - if (tests) { - (testConfig || (testConfig = {})).test = [tests]; - } - - if (light) { - (testConfig || (testConfig = {})).light = light; - } - - if (workerCount) { - (testConfig || (testConfig = {})).workerCount = workerCount; - } - - if (taskConfigFolder) { - (testConfig || (testConfig = {})).taskConfigFolder = taskConfigFolder; - } - - if (/^(\d+|full)$/.test(stackTraceLimit)) { - (testConfig || (testConfig = {})).stackTraceLimit = stackTraceLimit; - } - - if (testConfig) { - var testConfigContents = JSON.stringify(testConfig); - console.log('Running tests with config: ' + testConfigContents); - fs.writeFileSync('test.config', testConfigContents); - } +function writeTestConfigFile(tests, light, taskConfigsFolder, workerCount, stackTraceLimit) { + var testConfigContents = JSON.stringify({ + test: tests ? [tests] : undefined, + light: light, + workerCount: workerCount, + taskConfigsFolder: taskConfigsFolder, + stackTraceLimit: stackTraceLimit + }); + console.log('Running tests with config: ' + testConfigContents); + fs.writeFileSync('test.config', testConfigContents); } function deleteTemporaryProjectOutput() { @@ -758,257 +727,8 @@ function deleteTemporaryProjectOutput() { } } -function runTestsAndWriteOutput(file, defaultSubsets) { - cleanTestDirs(); - var tests = process.env.test || process.env.tests || process.env.t; - var light = process.env.light || false; - var testConfigFile = 'test.config'; - if (fs.existsSync(testConfigFile)) { - fs.unlinkSync(testConfigFile); - } - - writeTestConfigFile(testConfigFile, tests, light, 10); - - if (tests && tests.toLocaleLowerCase() === "rwc") { - testTimeout = 100000; - } - - var subsetRegexes; - var subsets; - if (tests || defaultSubsets.length === 0) { - subsetRegexes = [tests]; - subsets = [tests]; - } - else { - subsets = []; - subsetRegexes = []; - negations = []; - for (var i = 0; i < defaultSubsets.length; ++i) { - var subset = defaultSubsets[i]; - subsets.push(subset.name); - subsetRegexes.push(subset.pattern); - negations.push(subset.pattern); - } - - subsets.push("other"); - subsetRegexes.push("^(?!" + negations.join("|") + ")"); - } - - var out = fs.createWriteStream(file); - var outFileNames = subsetRegexes.length !== 1 ? [] : undefined; - var tapRange = /^(\d+)\.\.(\d+)(?:$|\r\n?|\n)/; - var tapOk = /^ok\s/; - var tapNotOk = /^not\sok\s/; - var tapComment = /^#(?: (tests|pass|fail) (\d+)$)?/; - var typeError = /^\s+TypeError:/; - var debugError = /^\s+Error:\sDebug\sFailure\./; - var progress = new ProgressBar(); - var totalTypeErrorCount = 0; - var totalDebugErrorCount = 0; - var totalReportedTestCount = 0; - var totalReportedPassCount = 0; - var totalReportedFailCount = 0; - var counter = subsetRegexes.length; - var errorStatus; - subsetRegexes.forEach(function (subsetRegex, i) { - var expectedTestCount = 0; - var testCount = 0; - var failureCount = 0; - var successCount = 0; - var reportedTestCount = 0; - var reportedPassCount = 0; - var reportedFailCount = 0; - var comments = []; - var typeErrorCount = 0; - var debugErrorCount = 0; - var outFileName; - var outFile; - if (subsetRegexes.length === 1) { - outFile = out; - } - else { - outFileName = path.join(os.tmpdir(), path.basename(file) + "." + i); - outFileNames[i] = outFileName; - outFile = fs.createWriteStream(outFileName); - } - - var args = []; - args.push("-R", "tap"); - args.push("--no-colors"); - args.push("-t", testTimeout); - if (subsetRegex) { - args.push("-g", '"' + subsetRegex + '"'); - } - - args.push(run); - - var cmd = "mocha " + args.join(" "); - if (subsetRegexes.length === 1) { - console.log(cmd); - } - - updateProgress(0); - - var p = child_process.spawn( - process.platform === "win32" ? "cmd" : "/bin/sh", - process.platform === "win32" ? ["/c", cmd] : ["-c", cmd], { - windowsVerbatimArguments: true, - env: { NODE_ENV: "development" } - }); - - var rl = readline.createInterface({ - input: p.stdout, - terminal: false - }); - - var start; - var end; - rl.on("line", function (line) { - if (!start) start = Date.now(); - var m = tapRange.exec(line); - if (m) { - expectedTestCount = parseInt(m[2]); - return; - } - - if (tapOk.test(line)) { - outFile.write(line.replace(/^ok\s+\d+\s+/, "ok ") + os.EOL); - successCount++; - } - else if (tapNotOk.test(line)) { - outFile.write(line.replace(/^not\s+ok\s+\d+\s+/, "not ok ") + os.EOL); - failureCount++; - } - else { - m = tapComment.exec(line); - if (m) { - if (m[1] === "tests") { - end = Date.now(); - reportedTestCount = parseInt(m[2]); - } - else if (m[1] === "pass") { - reportedPassCount = parseInt(m[2]); - } - else if (m[1] === "fail") { - reportedFailCount = parseInt(m[2]); - } - else { - outFile.write(line + os.EOL); - } - } - else { - outFile.write(line + os.EOL); - if (typeError.test(line)) { - typeErrorCount++; - } - else if (debugError.test(line)) { - debugErrorCount++; - } - } - return; - } - - testCount++; - - var percentComplete = testCount * 100 / expectedTestCount; - updateProgress(percentComplete); - }); - - p.on("exit", function (status) { - totalReportedTestCount += reportedTestCount; - totalReportedPassCount += reportedPassCount; - totalReportedFailCount += reportedFailCount; - totalTypeErrorCount += typeErrorCount; - totalDebugErrorCount += debugErrorCount; - - var duration = end - start; - var summary = - "pass: " + reportedPassCount + "/" + reportedTestCount + - ", duration: " + (duration / 1000).toFixed(2) + "s"; - - updateProgress(100, summary); - - if (subsetRegexes.length !== 1) { - outFile.close(); - } - - if (status && !errorStatus) { - errorStatus = status; - } - - counter--; - if (counter === 0) { - if (subsetRegexes.length !== 1) { - concatenate(); - } - else { - finish(); - } - } - }); - - function updateProgress(percentComplete, status) { - var title = status || (percentComplete < 100 ? "running..." : "done"); - if (subsetRegexes.length !== 1) { - title = "[" + subsets[i] + "] " + title; - } - - progress.update(percentComplete, - /*foregroundColor*/ failureCount > 0 - ? "red" - : successCount === expectedTestCount - ? "green" - : "cyan", - /*backgroundColor*/ "gray", - title, - i - ); - } - }); - - function concatenate() { - if (outFileNames.length > 0) { - var outFileName = outFileNames.shift(); - var outFile = fs.createReadStream(outFileName); - outFile.pipe(out, { end: false }); - outFile.on("end", function () { - fs.unlinkSync(outFileName); - concatenate(); - }); - return; - } - - finish(); - } - - function finish() { - out.write( - "# tests " + totalReportedTestCount + os.EOL + - "# pass " + totalReportedPassCount + os.EOL + - "# fail " + totalReportedFailCount + os.EOL); - console.log("# tests " + totalReportedTestCount); - console.log("# pass " + totalReportedPassCount); - console.log("# fail " + totalReportedFailCount); - - if (totalTypeErrorCount) { - console.log("# type errors " + totalTypeErrorCount); - } - - if (totalDebugErrorCount) { - console.log("# debug errors " + totalDebugErrorCount); - } - - deleteTemporaryProjectOutput(); - if (totalReportedFailCount) { - fail("Test failures reported: " + totalReportedFailCount); - } - else { - complete(); - } - } -} - -function runConsoleTests(defaultReporter, runInParallel, dirty) { +function runConsoleTests(defaultReporter, runInParallel) { + var dirty = process.env.dirty; if (!dirty) { cleanTestDirs(); } @@ -1016,7 +736,7 @@ function runConsoleTests(defaultReporter, runInParallel, dirty) { var debug = process.env.debug || process.env.d; tests = process.env.test || process.env.tests || process.env.t; var light = process.env.light || false; - var stackTraceLimit = process.env.stackTraceLimit || 1; + var stackTraceLimit = process.env.stackTraceLimit; var testConfigFile = 'test.config'; if (fs.existsSync(testConfigFile)) { fs.unlinkSync(testConfigFile); @@ -1134,33 +854,11 @@ task("runtests-parallel", ["build-rules", "tests", builtLocalDirectory], functio runConsoleTests('min', /*runInParallel*/ true); }, {async: true}); -desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true."); +desc("Runs the tests using the built run.js file. Optional arguments are: t[ests]=regex r[eporter]=[list|spec|json|] d[ebug]=true color[s]=false lint=true dirty=false."); task("runtests", ["build-rules", "tests", builtLocalDirectory], function() { runConsoleTests('mocha-fivemat-progress-reporter', /*runInParallel*/ false); }, {async: true}); -task("runtests-file", ["build-rules", "tests", builtLocalDirectory], function () { - var subsets = []; - var cores = os.cpus().length; - if (cores > 1) { - subsets.push({ name: "conformance", pattern: "^conformance\\b" }); - subsets.push({ name: "compiler", pattern: "^compiler\\b" }); - subsets.push({ name: "projects", pattern: "^Projects\\b" }); - if (cores > 4) { - subsets.push({ name: "fourslash", pattern: "^fourslash\\b" }); - subsets.push({ name: "fourslash (shims, shims-pp, server)", pattern: "^fourslash-" }); - } - else { - subsets.push({ name: "fourslash", pattern: "^fourslash" }); - } - } - runTestsAndWriteOutput("tests/baselines/local/testresults.tap", subsets); -}, { async: true }); - -task("runtests-dirty", ["build-rules", "tests", builtLocalDirectory], function () { - runConsoleTests("mocha-fivemat-progress-reporter", /*runInParallel*/ false, /*dirty*/ true); -}, { async: true }); - desc("Generates code coverage data via instanbul"); task("generate-code-coverage", ["tests", builtLocalDirectory], function () { var cmd = 'istanbul cover node_modules/mocha/bin/_mocha -- -R min -t ' + testTimeout + ' ' + run; @@ -1442,94 +1140,6 @@ task("lint-server", ["build-rules"], function() { } }); -function ProgressBar() { - this._progress = []; - this._lineCount = 0; -} -ProgressBar.prototype = { - progressChars: ["\u0020", "\u2591", "\u2592", "\u2593", "\u2588"], - colors: { - foreground: { - black: "\u001b[90m", - red: "\u001b[91m", - green: "\u001b[92m", - yellow: "\u001b[93m", - blue: "\u001b[94m", - magenta: "\u001b[95m", - cyan: "\u001b[96m", - white: "\u001b[97m", - gray: "\u001b[37m" - }, - background: { - black: "\u001b[40m", - red: "\u001b[41m", - green: "\u001b[42m", - yellow: "\u001b[43m", - blue: "\u001b[44m", - magenta: "\u001b[45m", - cyan: "\u001b[46m", - white: "\u001b[47m", - gray: "\u001b[100m" - }, - reset: "\u001b[0m" - }, - update: function (percentComplete, foregroundColor, backgroundColor, title, index) { - if (index === undefined) index = 0; - - var progress = ""; - for (var i = 0; i < 100; i += 4) { - progress += this.progressChars[Math.floor(Math.max(0, Math.min(4, percentComplete - i)))]; - } - - foregroundColor = foregroundColor && this.colors.foreground[foregroundColor]; - backgroundColor = backgroundColor && this.colors.background[backgroundColor]; - if (foregroundColor || backgroundColor) { - if (foregroundColor) { - progress = foregroundColor + progress; - } - if (backgroundColor) { - progress = backgroundColor + progress; - } - - progress += this.colors.reset; - } - - if (title) { - progress += " " + title; - } - - if (this._progress[index] !== progress) { - this._progress[index] = progress; - this._print(index); - } - }, - clear: function () { - if (this._lastProgress) { - readline.moveCursor(process.stdout, -process.stdout.columns, 0); - readline.clearLine(process.stdout, 1); - this._lastProgress = undefined; - this.visible = false; - } - }, - _print: function (index) { - readline.moveCursor(process.stdout, -process.stdout.columns, -this._lineCount); - var lineCount = 0; - for (var i = 0; i < this._progress.length; i++) { - if (i === index) { - readline.clearLine(process.stdout, 1); - process.stdout.write(this._progress[i] + os.EOL); - } - else { - readline.moveCursor(process.stdout, -process.stdout.columns, +1); - } - - lineCount++; - } - - this._lineCount = lineCount; - } -}; - function environmentVariableIsEnabled(name) { return /^(y(es)?|t(rue)?|on|enabled?|1|\+)$/.test(process.env[name]); } diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index b8c5fb7db3d79..d9272fb2b625d 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -374,12 +374,6 @@ namespace ts { type: "boolean", description: Diagnostics.Do_not_emit_use_strict_directives_in_module_output }, - { - name: "useLegacyEmitter", - type: "boolean", - experimental: true, - description: Diagnostics.Use_the_legacy_emitter_instead_of_the_transforming_emitter - }, { name: "listEmittedFiles", type: "boolean" diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 852b3ff9895d1..034bd27b1472a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2773,10 +2773,6 @@ "code": 6131 }, - "Use the legacy emitter instead of the transforming emitter.": { - "category": "Message", - "code": 6132 - }, "Variable '{0}' implicitly has an '{1}' type.": { "category": "Error", "code": 7005 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 185719abddcba..868ede1b0a848 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1,285 +1,11 @@ /// -/// +/// /// +/// +/// /* @internal */ namespace ts { - export function getResolvedExternalModuleName(host: EmitHost, file: SourceFile): string { - return file.moduleName || getExternalModuleNameFromPath(host, file.fileName); - } - - export function getExternalModuleNameFromDeclaration(host: EmitHost, resolver: EmitResolver, declaration: ImportEqualsDeclaration | ImportDeclaration | ExportDeclaration): string { - const file = resolver.getExternalModuleFileFromDeclaration(declaration); - if (!file || isDeclarationFile(file)) { - return undefined; - } - return getResolvedExternalModuleName(host, file); - } - - type DependencyGroup = Array; - - const enum Jump { - Break = 1 << 1, - Continue = 1 << 2, - Return = 1 << 3 - } - - const entities: Map = { - "quot": 0x0022, - "amp": 0x0026, - "apos": 0x0027, - "lt": 0x003C, - "gt": 0x003E, - "nbsp": 0x00A0, - "iexcl": 0x00A1, - "cent": 0x00A2, - "pound": 0x00A3, - "curren": 0x00A4, - "yen": 0x00A5, - "brvbar": 0x00A6, - "sect": 0x00A7, - "uml": 0x00A8, - "copy": 0x00A9, - "ordf": 0x00AA, - "laquo": 0x00AB, - "not": 0x00AC, - "shy": 0x00AD, - "reg": 0x00AE, - "macr": 0x00AF, - "deg": 0x00B0, - "plusmn": 0x00B1, - "sup2": 0x00B2, - "sup3": 0x00B3, - "acute": 0x00B4, - "micro": 0x00B5, - "para": 0x00B6, - "middot": 0x00B7, - "cedil": 0x00B8, - "sup1": 0x00B9, - "ordm": 0x00BA, - "raquo": 0x00BB, - "frac14": 0x00BC, - "frac12": 0x00BD, - "frac34": 0x00BE, - "iquest": 0x00BF, - "Agrave": 0x00C0, - "Aacute": 0x00C1, - "Acirc": 0x00C2, - "Atilde": 0x00C3, - "Auml": 0x00C4, - "Aring": 0x00C5, - "AElig": 0x00C6, - "Ccedil": 0x00C7, - "Egrave": 0x00C8, - "Eacute": 0x00C9, - "Ecirc": 0x00CA, - "Euml": 0x00CB, - "Igrave": 0x00CC, - "Iacute": 0x00CD, - "Icirc": 0x00CE, - "Iuml": 0x00CF, - "ETH": 0x00D0, - "Ntilde": 0x00D1, - "Ograve": 0x00D2, - "Oacute": 0x00D3, - "Ocirc": 0x00D4, - "Otilde": 0x00D5, - "Ouml": 0x00D6, - "times": 0x00D7, - "Oslash": 0x00D8, - "Ugrave": 0x00D9, - "Uacute": 0x00DA, - "Ucirc": 0x00DB, - "Uuml": 0x00DC, - "Yacute": 0x00DD, - "THORN": 0x00DE, - "szlig": 0x00DF, - "agrave": 0x00E0, - "aacute": 0x00E1, - "acirc": 0x00E2, - "atilde": 0x00E3, - "auml": 0x00E4, - "aring": 0x00E5, - "aelig": 0x00E6, - "ccedil": 0x00E7, - "egrave": 0x00E8, - "eacute": 0x00E9, - "ecirc": 0x00EA, - "euml": 0x00EB, - "igrave": 0x00EC, - "iacute": 0x00ED, - "icirc": 0x00EE, - "iuml": 0x00EF, - "eth": 0x00F0, - "ntilde": 0x00F1, - "ograve": 0x00F2, - "oacute": 0x00F3, - "ocirc": 0x00F4, - "otilde": 0x00F5, - "ouml": 0x00F6, - "divide": 0x00F7, - "oslash": 0x00F8, - "ugrave": 0x00F9, - "uacute": 0x00FA, - "ucirc": 0x00FB, - "uuml": 0x00FC, - "yacute": 0x00FD, - "thorn": 0x00FE, - "yuml": 0x00FF, - "OElig": 0x0152, - "oelig": 0x0153, - "Scaron": 0x0160, - "scaron": 0x0161, - "Yuml": 0x0178, - "fnof": 0x0192, - "circ": 0x02C6, - "tilde": 0x02DC, - "Alpha": 0x0391, - "Beta": 0x0392, - "Gamma": 0x0393, - "Delta": 0x0394, - "Epsilon": 0x0395, - "Zeta": 0x0396, - "Eta": 0x0397, - "Theta": 0x0398, - "Iota": 0x0399, - "Kappa": 0x039A, - "Lambda": 0x039B, - "Mu": 0x039C, - "Nu": 0x039D, - "Xi": 0x039E, - "Omicron": 0x039F, - "Pi": 0x03A0, - "Rho": 0x03A1, - "Sigma": 0x03A3, - "Tau": 0x03A4, - "Upsilon": 0x03A5, - "Phi": 0x03A6, - "Chi": 0x03A7, - "Psi": 0x03A8, - "Omega": 0x03A9, - "alpha": 0x03B1, - "beta": 0x03B2, - "gamma": 0x03B3, - "delta": 0x03B4, - "epsilon": 0x03B5, - "zeta": 0x03B6, - "eta": 0x03B7, - "theta": 0x03B8, - "iota": 0x03B9, - "kappa": 0x03BA, - "lambda": 0x03BB, - "mu": 0x03BC, - "nu": 0x03BD, - "xi": 0x03BE, - "omicron": 0x03BF, - "pi": 0x03C0, - "rho": 0x03C1, - "sigmaf": 0x03C2, - "sigma": 0x03C3, - "tau": 0x03C4, - "upsilon": 0x03C5, - "phi": 0x03C6, - "chi": 0x03C7, - "psi": 0x03C8, - "omega": 0x03C9, - "thetasym": 0x03D1, - "upsih": 0x03D2, - "piv": 0x03D6, - "ensp": 0x2002, - "emsp": 0x2003, - "thinsp": 0x2009, - "zwnj": 0x200C, - "zwj": 0x200D, - "lrm": 0x200E, - "rlm": 0x200F, - "ndash": 0x2013, - "mdash": 0x2014, - "lsquo": 0x2018, - "rsquo": 0x2019, - "sbquo": 0x201A, - "ldquo": 0x201C, - "rdquo": 0x201D, - "bdquo": 0x201E, - "dagger": 0x2020, - "Dagger": 0x2021, - "bull": 0x2022, - "hellip": 0x2026, - "permil": 0x2030, - "prime": 0x2032, - "Prime": 0x2033, - "lsaquo": 0x2039, - "rsaquo": 0x203A, - "oline": 0x203E, - "frasl": 0x2044, - "euro": 0x20AC, - "image": 0x2111, - "weierp": 0x2118, - "real": 0x211C, - "trade": 0x2122, - "alefsym": 0x2135, - "larr": 0x2190, - "uarr": 0x2191, - "rarr": 0x2192, - "darr": 0x2193, - "harr": 0x2194, - "crarr": 0x21B5, - "lArr": 0x21D0, - "uArr": 0x21D1, - "rArr": 0x21D2, - "dArr": 0x21D3, - "hArr": 0x21D4, - "forall": 0x2200, - "part": 0x2202, - "exist": 0x2203, - "empty": 0x2205, - "nabla": 0x2207, - "isin": 0x2208, - "notin": 0x2209, - "ni": 0x220B, - "prod": 0x220F, - "sum": 0x2211, - "minus": 0x2212, - "lowast": 0x2217, - "radic": 0x221A, - "prop": 0x221D, - "infin": 0x221E, - "ang": 0x2220, - "and": 0x2227, - "or": 0x2228, - "cap": 0x2229, - "cup": 0x222A, - "int": 0x222B, - "there4": 0x2234, - "sim": 0x223C, - "cong": 0x2245, - "asymp": 0x2248, - "ne": 0x2260, - "equiv": 0x2261, - "le": 0x2264, - "ge": 0x2265, - "sub": 0x2282, - "sup": 0x2283, - "nsub": 0x2284, - "sube": 0x2286, - "supe": 0x2287, - "oplus": 0x2295, - "otimes": 0x2297, - "perp": 0x22A5, - "sdot": 0x22C5, - "lceil": 0x2308, - "rceil": 0x2309, - "lfloor": 0x230A, - "rfloor": 0x230B, - "lang": 0x2329, - "rang": 0x232A, - "loz": 0x25CA, - "spades": 0x2660, - "clubs": 0x2663, - "hearts": 0x2665, - "diams": 0x2666 - }; - // Flags enum to track count of temp variables and a few dedicated names const enum TempFlags { Auto = 0x00000000, // No preferred name @@ -287,56 +13,11 @@ namespace ts { _i = 0x10000000, // Use/preference flag for '_i' } - const enum CopyDirection { - ToOriginal, - ToOutParameter - } - - /** - * If loop contains block scoped binding captured in some function then loop body is converted to a function. - * Lexical bindings declared in loop initializer will be passed into the loop body function as parameters, - * however if this binding is modified inside the body - this new value should be propagated back to the original binding. - * This is done by declaring new variable (out parameter holder) outside of the loop for every binding that is reassigned inside the body. - * On every iteration this variable is initialized with value of corresponding binding. - * At every point where control flow leaves the loop either explicitly (break/continue) or implicitly (at the end of loop body) - * we copy the value inside the loop to the out parameter holder. - * - * for (let x;;) { - * let a = 1; - * let b = () => a; - * x++ - * if (...) break; - * ... - * } - * - * will be converted to - * - * var out_x; - * var loop = function(x) { - * var a = 1; - * var b = function() { return a; } - * x++; - * if (...) return out_x = x, "break"; - * ... - * out_x = x; - * } - * for (var x;;) { - * out_x = x; - * var state = loop(x); - * x = out_x; - * if (state === "break") break; - * } - * - * NOTE: values to out parameters are not copies if loop is abrupted with 'return' - in this case this will end the entire enclosing function - * so nobody can observe this new value. - */ - interface LoopOutParameter { - originalName: Identifier; - outParamName: string; - } - // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile): EmitResult { + const delimiters = createDelimiterMap(); + const brackets = createBracketsMap(); + // emit output for the __extends helper function const extendsHelper = ` var __extends = (this && this.__extends) || function (d, b) { @@ -345,6 +26,9 @@ var __extends = (this && this.__extends) || function (d, b) { d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); };`; + // Emit output for the __assign helper function. + // This is typically used for JSX spread attributes, + // and can be used for object literal spread properties. const assignHelper = ` var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { @@ -376,6 +60,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } };`; + // emit output for the __awaiter helper function const awaiterHelper = ` var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { @@ -386,17 +71,111 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); };`; + // emit output for the __export helper function + const exportStarHelper = ` +function __export(m) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; +}`; + + // emit output for the UMD helper function. + const umdHelper = ` +(function (dependencies, factory) { + if (typeof module === 'object' && typeof module.exports === 'object') { + var v = factory(require, exports); if (v !== undefined) module.exports = v; + } + else if (typeof define === 'function' && define.amd) { + define(dependencies, factory); + } +})`; + + const superHelper = ` +const _super = name => super[name];`; + + const advancedSuperHelper = ` +const _super = (function (geti, seti) { + const cache = Object.create(null); + return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } }); +})(name => super[name], (name, value) => super[name] = value);`; + const compilerOptions = host.getCompilerOptions(); const languageVersion = getEmitScriptTarget(compilerOptions); - const modulekind = getEmitModuleKind(compilerOptions); + const moduleKind = getEmitModuleKind(compilerOptions); const sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined; const emitterDiagnostics = createDiagnosticCollection(); - let emitSkipped = false; const newLine = host.getNewLine(); + const transformers = getTransformers(compilerOptions); + const writer = createTextWriter(newLine); + const { + write, + writeLine, + increaseIndent, + decreaseIndent + } = writer; + + const sourceMap = createSourceMapWriter(host, writer); + const { + emitStart, + emitEnd, + emitTokenStart, + emitTokenEnd + } = sourceMap; + + const comments = createCommentWriter(host, writer, sourceMap); + const { + emitNodeWithComments, + emitBodyWithDetachedComments, + emitTrailingCommentsOfPosition + } = comments; + + let nodeIdToGeneratedName: string[]; + let autoGeneratedIdToGeneratedName: string[]; + let generatedNameSet: Map; + let tempFlags: TempFlags; + let currentSourceFile: SourceFile; + let currentText: string; + let currentFileIdentifiers: Map; + let extendsEmitted: boolean; + let assignEmitted: boolean; + let decorateEmitted: boolean; + let paramEmitted: boolean; + let awaiterEmitted: boolean; + let isOwnFileEmit: boolean; + let emitSkipped = false; + + performance.emit("beforeTransform"); + const transformStart = performance.mark(); + + // Transform the source files + const transformed = transformFiles( + resolver, + host, + getSourceFilesToEmit(host, targetSourceFile), + transformers); + + performance.measure("transformTime", transformStart); + performance.emit("afterTransform"); + + // Extract helpers from the result + const { + getTokenSourceMapRange, + isSubstitutionEnabled, + isEmitNotificationEnabled, + onSubstituteNode, + onEmitNode + } = transformed; - const emitJavaScript = createFileEmitter(); - forEachExpectedEmitFile(host, emitFile, targetSourceFile); + performance.emit("beforePrint"); + const printStart = performance.mark(); + + // Emit each output file + forEachTransformedEmitFile(host, transformed.getSourceFiles(), emitFile); + + // Clean up after transformation + transformed.dispose(); + + performance.measure("printTime", printStart); + performance.emit("afterPrint"); return { emitSkipped, @@ -405,7877 +184,2735 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge sourceMaps: sourceMapDataList }; - function isUniqueLocalName(name: string, container: Node): boolean { - for (let node = container; isNodeDescendantOf(node, container); node = node.nextContainer) { - if (node.locals && hasProperty(node.locals, name)) { - // We conservatively include alias symbols to cover cases where they're emitted as locals - if (node.locals[name].flags & (SymbolFlags.Value | SymbolFlags.ExportValue | SymbolFlags.Alias)) { - return false; - } - } - } - return true; - } - - interface ConvertedLoopState { - /* - * set of labels that occurred inside the converted loop - * used to determine if labeled jump can be emitted as is or it should be dispatched to calling code - */ - labels?: Map; - /* - * collection of labeled jumps that transfer control outside the converted loop. - * maps store association 'label -> labelMarker' where - * - label - value of label as it appear in code - * - label marker - return value that should be interpreted by calling code as 'jump to