diff --git a/src/compiler/emitter.js b/src/compiler/emitter.js
deleted file mode 100644
index a00f3a4dde3..00000000000
--- a/src/compiler/emitter.js
+++ /dev/null
@@ -1,5229 +0,0 @@
-///
-///
-/* @internal */
-var ts;
-(function (ts) {
- function isExternalModuleOrDeclarationFile(sourceFile) {
- return ts.isExternalModule(sourceFile) || ts.isDeclarationFile(sourceFile);
- }
- ts.isExternalModuleOrDeclarationFile = isExternalModuleOrDeclarationFile;
- // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
- function emitFiles(resolver, host, targetSourceFile) {
- // emit output for the __extends helper function
- var extendsHelper = "\nvar __extends = this.__extends || function (d, b) {\n for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];\n function __() { this.constructor = d; }\n __.prototype = b.prototype;\n d.prototype = new __();\n};";
- // emit output for the __decorate helper function
- var decorateHelper = "\nvar __decorate = this.__decorate || (typeof Reflect === \"object\" && Reflect.decorate) || function (decorators, target, key, desc) {\n switch (arguments.length) {\n case 2: return decorators.reduceRight(function(o, d) { return (d && d(o)) || o; }, target);\n case 3: return decorators.reduceRight(function(o, d) { return (d && d(target, key)), void 0; }, void 0);\n case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc);\n }\n};";
- // emit output for the __metadata helper function
- var metadataHelper = "\nvar __metadata = this.__metadata || (typeof Reflect === \"object\" && Reflect.metadata) || function () { };";
- // emit output for the __param helper function
- var paramHelper = "\nvar __param = this.__param || function(index, decorator) { return function (target, key) { decorator(target, key, index); } };";
- var compilerOptions = host.getCompilerOptions();
- var languageVersion = compilerOptions.target || 0 /* ES3 */;
- var sourceMapDataList = compilerOptions.sourceMap ? [] : undefined;
- var diagnostics = [];
- var newLine = host.getNewLine();
- if (targetSourceFile === undefined) {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (ts.shouldEmitToOwnFile(sourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, ".js");
- emitFile(jsFilePath, sourceFile);
- }
- });
- if (compilerOptions.out) {
- emitFile(compilerOptions.out);
- }
- }
- else {
- // targetSourceFile is specified (e.g calling emitter from language service or calling getSemanticDiagnostic from language service)
- if (ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
- var jsFilePath = ts.getOwnEmitOutputFilePath(targetSourceFile, host, ".js");
- emitFile(jsFilePath, targetSourceFile);
- }
- else if (!ts.isDeclarationFile(targetSourceFile) && compilerOptions.out) {
- emitFile(compilerOptions.out);
- }
- }
- // Sort and make the unique list of diagnostics
- diagnostics = ts.sortAndDeduplicateDiagnostics(diagnostics);
- return {
- emitSkipped: false,
- diagnostics: diagnostics,
- sourceMaps: sourceMapDataList
- };
- function isNodeDescendentOf(node, ancestor) {
- while (node) {
- if (node === ancestor)
- return true;
- node = node.parent;
- }
- return false;
- }
- function isUniqueLocalName(name, container) {
- for (var node = container; isNodeDescendentOf(node, container); node = node.nextContainer) {
- if (node.locals && ts.hasProperty(node.locals, name)) {
- // We conservatively include alias symbols to cover cases where they're emitted as locals
- if (node.locals[name].flags & (107455 /* Value */ | 1048576 /* ExportValue */ | 8388608 /* Alias */)) {
- return false;
- }
- }
- }
- return true;
- }
- function emitJavaScript(jsFilePath, root) {
- var writer = ts.createTextWriter(newLine);
- var write = writer.write;
- var writeTextOfNode = writer.writeTextOfNode;
- var writeLine = writer.writeLine;
- var increaseIndent = writer.increaseIndent;
- var decreaseIndent = writer.decreaseIndent;
- var currentSourceFile;
- // name of an exporter function if file is a System external module
- // System.register([...], function () {...})
- // exporting in System modules looks like:
- // export var x; ... x = 1
- // =>
- // var x;... exporter("x", x = 1)
- var exportFunctionForFile;
- var generatedNameSet = {};
- var nodeToGeneratedName = [];
- var blockScopedVariableToGeneratedName;
- var computedPropertyNamesToGeneratedNames;
- var extendsEmitted = false;
- var decorateEmitted = false;
- var paramEmitted = false;
- var tempFlags = 0;
- var tempVariables;
- var tempParameters;
- var externalImports;
- var exportSpecifiers;
- var exportEquals;
- var hasExportStars;
- /** write emitted output to disk*/
- var writeEmittedFiles = writeJavaScriptFile;
- var detachedCommentsInfo;
- var writeComment = ts.writeCommentRange;
- /** Emit a node */
- var emit = emitNodeWithoutSourceMap;
- /** Called just before starting emit of a node */
- var emitStart = function (node) { };
- /** Called once the emit of the node is done */
- var emitEnd = function (node) { };
- /** Emit the text for the given token that comes after startPos
- * This by default writes the text provided with the given tokenKind
- * but if optional emitFn callback is provided the text is emitted using the callback instead of default text
- * @param tokenKind the kind of the token to search and emit
- * @param startPos the position in the source to start searching for the token
- * @param emitFn if given will be invoked to emit the text instead of actual token emit */
- var emitToken = emitTokenText;
- /** Called to before starting the lexical scopes as in function/class in the emitted code because of node
- * @param scopeDeclaration node that starts the lexical scope
- * @param scopeName Optional name of this scope instead of deducing one from the declaration node */
- var scopeEmitStart = function (scopeDeclaration, scopeName) { };
- /** Called after coming out of the scope */
- var scopeEmitEnd = function () { };
- /** Sourcemap data that will get encoded */
- var sourceMapData;
- if (compilerOptions.sourceMap) {
- initializeEmitterWithSourceMaps();
- }
- if (root) {
- // Do not call emit directly. It does not set the currentSourceFile.
- emitSourceFile(root);
- }
- else {
- ts.forEach(host.getSourceFiles(), function (sourceFile) {
- if (!isExternalModuleOrDeclarationFile(sourceFile)) {
- emitSourceFile(sourceFile);
- }
- });
- }
- writeLine();
- writeEmittedFiles(writer.getText(), compilerOptions.emitBOM);
- return;
- function emitSourceFile(sourceFile) {
- currentSourceFile = sourceFile;
- exportFunctionForFile = undefined;
- emit(sourceFile);
- }
- function isUniqueName(name) {
- return !resolver.hasGlobalName(name) &&
- !ts.hasProperty(currentSourceFile.identifiers, name) &&
- !ts.hasProperty(generatedNameSet, name);
- }
- // Return the next available name in the pattern _a ... _z, _0, _1, ...
- // TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name.
- // Note that names generated by makeTempVariableName and makeUniqueName will never conflict.
- function makeTempVariableName(flags) {
- if (flags && !(tempFlags & flags)) {
- var name = flags === 268435456 /* _i */ ? "_i" : "_n";
- if (isUniqueName(name)) {
- tempFlags |= flags;
- return name;
- }
- }
- while (true) {
- var count = tempFlags & 268435455 /* CountMask */;
- tempFlags++;
- // Skip over 'i' and 'n'
- if (count !== 8 && count !== 13) {
- var name_1 = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26);
- if (isUniqueName(name_1)) {
- return name_1;
- }
- }
- }
- }
- // Generate a name that is unique within the current file and doesn't conflict with any names
- // in global scope. The name is formed by adding an '_n' suffix to the specified base name,
- // where n is a positive integer. Note that names generated by makeTempVariableName and
- // makeUniqueName are guaranteed to never conflict.
- function makeUniqueName(baseName) {
- // Find the first unique 'name_n', where n is a positive number
- if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) {
- baseName += "_";
- }
- var i = 1;
- while (true) {
- var generatedName = baseName + i;
- if (isUniqueName(generatedName)) {
- return generatedNameSet[generatedName] = generatedName;
- }
- i++;
- }
- }
- function assignGeneratedName(node, name) {
- nodeToGeneratedName[ts.getNodeId(node)] = ts.unescapeIdentifier(name);
- }
- function generateNameForFunctionOrClassDeclaration(node) {
- if (!node.name) {
- assignGeneratedName(node, makeUniqueName("default"));
- }
- }
- function generateNameForModuleOrEnum(node) {
- if (node.name.kind === 65 /* Identifier */) {
- var name_2 = node.name.text;
- // Use module/enum name itself if it is unique, otherwise make a unique variation
- assignGeneratedName(node, isUniqueLocalName(name_2, node) ? name_2 : makeUniqueName(name_2));
- }
- }
- function generateNameForImportOrExportDeclaration(node) {
- var expr = ts.getExternalModuleName(node);
- var baseName = expr.kind === 8 /* StringLiteral */ ?
- ts.escapeIdentifier(ts.makeIdentifierFromModuleName(expr.text)) : "module";
- assignGeneratedName(node, makeUniqueName(baseName));
- }
- function generateNameForImportDeclaration(node) {
- if (node.importClause) {
- generateNameForImportOrExportDeclaration(node);
- }
- }
- function generateNameForExportDeclaration(node) {
- if (node.moduleSpecifier) {
- generateNameForImportOrExportDeclaration(node);
- }
- }
- function generateNameForExportAssignment(node) {
- if (node.expression && node.expression.kind !== 65 /* Identifier */) {
- assignGeneratedName(node, makeUniqueName("default"));
- }
- }
- function generateNameForNode(node) {
- switch (node.kind) {
- case 200 /* FunctionDeclaration */:
- case 201 /* ClassDeclaration */:
- case 174 /* ClassExpression */:
- generateNameForFunctionOrClassDeclaration(node);
- break;
- case 205 /* ModuleDeclaration */:
- generateNameForModuleOrEnum(node);
- generateNameForNode(node.body);
- break;
- case 204 /* EnumDeclaration */:
- generateNameForModuleOrEnum(node);
- break;
- case 209 /* ImportDeclaration */:
- generateNameForImportDeclaration(node);
- break;
- case 215 /* ExportDeclaration */:
- generateNameForExportDeclaration(node);
- break;
- case 214 /* ExportAssignment */:
- generateNameForExportAssignment(node);
- break;
- }
- }
- function getGeneratedNameForNode(node) {
- var nodeId = ts.getNodeId(node);
- if (!nodeToGeneratedName[nodeId]) {
- generateNameForNode(node);
- }
- return nodeToGeneratedName[nodeId];
- }
- function initializeEmitterWithSourceMaps() {
- var sourceMapDir; // The directory in which sourcemap will be
- // Current source map file and its index in the sources list
- var sourceMapSourceIndex = -1;
- // Names and its index map
- var sourceMapNameIndexMap = {};
- var sourceMapNameIndices = [];
- function getSourceMapNameIndex() {
- return sourceMapNameIndices.length ? lastOrUndefined(sourceMapNameIndices) : -1;
- }
- // Last recorded and encoded spans
- var lastRecordedSourceMapSpan;
- var lastEncodedSourceMapSpan = {
- emittedLine: 1,
- emittedColumn: 1,
- sourceLine: 1,
- sourceColumn: 1,
- sourceIndex: 0
- };
- var lastEncodedNameIndex = 0;
- // Encoding for sourcemap span
- function encodeLastRecordedSourceMapSpan() {
- if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) {
- return;
- }
- var prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn;
- // Line/Comma delimiters
- if (lastEncodedSourceMapSpan.emittedLine == lastRecordedSourceMapSpan.emittedLine) {
- // Emit comma to separate the entry
- if (sourceMapData.sourceMapMappings) {
- sourceMapData.sourceMapMappings += ",";
- }
- }
- else {
- // Emit line delimiters
- for (var encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) {
- sourceMapData.sourceMapMappings += ";";
- }
- prevEncodedEmittedColumn = 1;
- }
- // 1. Relative Column 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn);
- // 2. Relative sourceIndex
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex);
- // 3. Relative sourceLine 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine);
- // 4. Relative sourceColumn 0 based
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn);
- // 5. Relative namePosition 0 based
- if (lastRecordedSourceMapSpan.nameIndex >= 0) {
- sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex);
- lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex;
- }
- lastEncodedSourceMapSpan = lastRecordedSourceMapSpan;
- sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan);
- function base64VLQFormatEncode(inValue) {
- function base64FormatEncode(inValue) {
- if (inValue < 64) {
- return 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.charAt(inValue);
- }
- throw TypeError(inValue + ": not a 64 based value");
- }
- // Add a new least significant bit that has the sign of the value.
- // if negative number the least significant bit that gets added to the number has value 1
- // else least significant bit value that gets added is 0
- // eg. -1 changes to binary : 01 [1] => 3
- // +1 changes to binary : 01 [0] => 2
- if (inValue < 0) {
- inValue = ((-inValue) << 1) + 1;
- }
- else {
- inValue = inValue << 1;
- }
- // Encode 5 bits at a time starting from least significant bits
- var encodedStr = "";
- do {
- var currentDigit = inValue & 31; // 11111
- inValue = inValue >> 5;
- if (inValue > 0) {
- // There are still more digits to decode, set the msb (6th bit)
- currentDigit = currentDigit | 32;
- }
- encodedStr = encodedStr + base64FormatEncode(currentDigit);
- } while (inValue > 0);
- return encodedStr;
- }
- }
- function recordSourceMapSpan(pos) {
- var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSourceFile, pos);
- // Convert the location to be one-based.
- sourceLinePos.line++;
- sourceLinePos.character++;
- var emittedLine = writer.getLine();
- var emittedColumn = writer.getColumn();
- // If this location wasn't recorded or the location in source is going backwards, record the span
- if (!lastRecordedSourceMapSpan ||
- lastRecordedSourceMapSpan.emittedLine != emittedLine ||
- lastRecordedSourceMapSpan.emittedColumn != emittedColumn ||
- (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex &&
- (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line ||
- (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) {
- // Encode the last recordedSpan before assigning new
- encodeLastRecordedSourceMapSpan();
- // New span
- lastRecordedSourceMapSpan = {
- emittedLine: emittedLine,
- emittedColumn: emittedColumn,
- sourceLine: sourceLinePos.line,
- sourceColumn: sourceLinePos.character,
- nameIndex: getSourceMapNameIndex(),
- sourceIndex: sourceMapSourceIndex
- };
- }
- else {
- // Take the new pos instead since there is no change in emittedLine and column since last location
- lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line;
- lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character;
- lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex;
- }
- }
- function recordEmitNodeStartSpan(node) {
- // Get the token pos after skipping to the token (ignoring the leading trivia)
- recordSourceMapSpan(ts.skipTrivia(currentSourceFile.text, node.pos));
- }
- function recordEmitNodeEndSpan(node) {
- recordSourceMapSpan(node.end);
- }
- function writeTextWithSpanRecord(tokenKind, startPos, emitFn) {
- var tokenStartPos = ts.skipTrivia(currentSourceFile.text, startPos);
- recordSourceMapSpan(tokenStartPos);
- var tokenEndPos = emitTokenText(tokenKind, tokenStartPos, emitFn);
- recordSourceMapSpan(tokenEndPos);
- return tokenEndPos;
- }
- function recordNewSourceFileStart(node) {
- // Add the file to tsFilePaths
- // If sourceroot option: Use the relative path corresponding to the common directory path
- // otherwise source locations relative to map file location
- var sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir;
- sourceMapData.sourceMapSources.push(ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, node.fileName, host.getCurrentDirectory(), host.getCanonicalFileName,
- /*isAbsolutePathAnUrl*/ true));
- sourceMapSourceIndex = sourceMapData.sourceMapSources.length - 1;
- // The one that can be used from program to get the actual source file
- sourceMapData.inputSourceFileNames.push(node.fileName);
- }
- function recordScopeNameOfNode(node, scopeName) {
- function recordScopeNameIndex(scopeNameIndex) {
- sourceMapNameIndices.push(scopeNameIndex);
- }
- function recordScopeNameStart(scopeName) {
- var scopeNameIndex = -1;
- if (scopeName) {
- var parentIndex = getSourceMapNameIndex();
- if (parentIndex !== -1) {
- // Child scopes are always shown with a dot (even if they have no name),
- // unless it is a computed property. Then it is shown with brackets,
- // but the brackets are included in the name.
- var name_3 = node.name;
- if (!name_3 || name_3.kind !== 127 /* ComputedPropertyName */) {
- scopeName = "." + scopeName;
- }
- scopeName = sourceMapData.sourceMapNames[parentIndex] + scopeName;
- }
- scopeNameIndex = ts.getProperty(sourceMapNameIndexMap, scopeName);
- if (scopeNameIndex === undefined) {
- scopeNameIndex = sourceMapData.sourceMapNames.length;
- sourceMapData.sourceMapNames.push(scopeName);
- sourceMapNameIndexMap[scopeName] = scopeNameIndex;
- }
- }
- recordScopeNameIndex(scopeNameIndex);
- }
- if (scopeName) {
- // The scope was already given a name use it
- recordScopeNameStart(scopeName);
- }
- else if (node.kind === 200 /* FunctionDeclaration */ ||
- node.kind === 162 /* FunctionExpression */ ||
- node.kind === 134 /* MethodDeclaration */ ||
- node.kind === 133 /* MethodSignature */ ||
- node.kind === 136 /* GetAccessor */ ||
- node.kind === 137 /* SetAccessor */ ||
- node.kind === 205 /* ModuleDeclaration */ ||
- node.kind === 201 /* ClassDeclaration */ ||
- node.kind === 204 /* EnumDeclaration */) {
- // Declaration and has associated name use it
- if (node.name) {
- var name_4 = node.name;
- // For computed property names, the text will include the brackets
- scopeName = name_4.kind === 127 /* ComputedPropertyName */
- ? ts.getTextOfNode(name_4)
- : node.name.text;
- }
- recordScopeNameStart(scopeName);
- }
- else {
- // Block just use the name from upper level scope
- recordScopeNameIndex(getSourceMapNameIndex());
- }
- }
- function recordScopeNameEnd() {
- sourceMapNameIndices.pop();
- }
- ;
- function writeCommentRangeWithMap(curentSourceFile, writer, comment, newLine) {
- recordSourceMapSpan(comment.pos);
- ts.writeCommentRange(currentSourceFile, writer, comment, newLine);
- recordSourceMapSpan(comment.end);
- }
- function serializeSourceMapContents(version, file, sourceRoot, sources, names, mappings) {
- if (typeof JSON !== "undefined") {
- return JSON.stringify({
- version: version,
- file: file,
- sourceRoot: sourceRoot,
- sources: sources,
- names: names,
- mappings: mappings
- });
- }
- return "{\"version\":" + version + ",\"file\":\"" + ts.escapeString(file) + "\",\"sourceRoot\":\"" + ts.escapeString(sourceRoot) + "\",\"sources\":[" + serializeStringArray(sources) + "],\"names\":[" + serializeStringArray(names) + "],\"mappings\":\"" + ts.escapeString(mappings) + "\"}";
- function serializeStringArray(list) {
- var output = "";
- for (var i = 0, n = list.length; i < n; i++) {
- if (i) {
- output += ",";
- }
- output += "\"" + ts.escapeString(list[i]) + "\"";
- }
- return output;
- }
- }
- function writeJavaScriptAndSourceMapFile(emitOutput, writeByteOrderMark) {
- // Write source map file
- encodeLastRecordedSourceMapSpan();
- ts.writeFile(host, diagnostics, sourceMapData.sourceMapFilePath, serializeSourceMapContents(3, sourceMapData.sourceMapFile, sourceMapData.sourceMapSourceRoot, sourceMapData.sourceMapSources, sourceMapData.sourceMapNames, sourceMapData.sourceMapMappings), false);
- sourceMapDataList.push(sourceMapData);
- // Write sourcemap url to the js file and write the js file
- writeJavaScriptFile(emitOutput + "//# sourceMappingURL=" + sourceMapData.jsSourceMappingURL, writeByteOrderMark);
- }
- // Initialize source map data
- var sourceMapJsFile = ts.getBaseFileName(ts.normalizeSlashes(jsFilePath));
- sourceMapData = {
- sourceMapFilePath: jsFilePath + ".map",
- jsSourceMappingURL: sourceMapJsFile + ".map",
- sourceMapFile: sourceMapJsFile,
- sourceMapSourceRoot: compilerOptions.sourceRoot || "",
- sourceMapSources: [],
- inputSourceFileNames: [],
- sourceMapNames: [],
- sourceMapMappings: "",
- sourceMapDecodedMappings: []
- };
- // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the
- // relative paths of the sources list in the sourcemap
- sourceMapData.sourceMapSourceRoot = ts.normalizeSlashes(sourceMapData.sourceMapSourceRoot);
- if (sourceMapData.sourceMapSourceRoot.length && sourceMapData.sourceMapSourceRoot.charCodeAt(sourceMapData.sourceMapSourceRoot.length - 1) !== 47 /* slash */) {
- sourceMapData.sourceMapSourceRoot += ts.directorySeparator;
- }
- if (compilerOptions.mapRoot) {
- sourceMapDir = ts.normalizeSlashes(compilerOptions.mapRoot);
- if (root) {
- // For modules or multiple emit files the mapRoot will have directory structure like the sources
- // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map
- sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(root, host, sourceMapDir));
- }
- if (!ts.isRootedDiskPath(sourceMapDir) && !ts.isUrl(sourceMapDir)) {
- // The relative paths are relative to the common directory
- sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir);
- sourceMapData.jsSourceMappingURL = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(jsFilePath)), ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), host.getCurrentDirectory(), host.getCanonicalFileName,
- /*isAbsolutePathAnUrl*/ true);
- }
- else {
- sourceMapData.jsSourceMappingURL = ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL);
- }
- }
- else {
- sourceMapDir = ts.getDirectoryPath(ts.normalizePath(jsFilePath));
- }
- function emitNodeWithSourceMap(node, allowGeneratedIdentifiers) {
- if (node) {
- if (ts.nodeIsSynthesized(node)) {
- return emitNodeWithoutSourceMap(node, false);
- }
- if (node.kind != 227 /* SourceFile */) {
- recordEmitNodeStartSpan(node);
- emitNodeWithoutSourceMap(node, allowGeneratedIdentifiers);
- recordEmitNodeEndSpan(node);
- }
- else {
- recordNewSourceFileStart(node);
- emitNodeWithoutSourceMap(node, false);
- }
- }
- }
- writeEmittedFiles = writeJavaScriptAndSourceMapFile;
- emit = emitNodeWithSourceMap;
- emitStart = recordEmitNodeStartSpan;
- emitEnd = recordEmitNodeEndSpan;
- emitToken = writeTextWithSpanRecord;
- scopeEmitStart = recordScopeNameOfNode;
- scopeEmitEnd = recordScopeNameEnd;
- writeComment = writeCommentRangeWithMap;
- }
- function writeJavaScriptFile(emitOutput, writeByteOrderMark) {
- ts.writeFile(host, diagnostics, jsFilePath, emitOutput, writeByteOrderMark);
- }
- // Create a temporary variable with a unique unused name.
- function createTempVariable(flags) {
- var result = ts.createSynthesizedNode(65 /* Identifier */);
- result.text = makeTempVariableName(flags);
- return result;
- }
- function recordTempDeclaration(name) {
- if (!tempVariables) {
- tempVariables = [];
- }
- tempVariables.push(name);
- }
- function createAndRecordTempVariable(flags) {
- var temp = createTempVariable(flags);
- recordTempDeclaration(temp);
- return temp;
- }
- function emitTempDeclarations(newLine) {
- if (tempVariables) {
- if (newLine) {
- writeLine();
- }
- else {
- write(" ");
- }
- write("var ");
- emitCommaList(tempVariables);
- write(";");
- }
- }
- function emitTokenText(tokenKind, startPos, emitFn) {
- var tokenString = ts.tokenToString(tokenKind);
- if (emitFn) {
- emitFn();
- }
- else {
- write(tokenString);
- }
- return startPos + tokenString.length;
- }
- function emitOptional(prefix, node) {
- if (node) {
- write(prefix);
- emit(node);
- }
- }
- function emitParenthesizedIf(node, parenthesized) {
- if (parenthesized) {
- write("(");
- }
- emit(node);
- if (parenthesized) {
- write(")");
- }
- }
- function emitTrailingCommaIfPresent(nodeList) {
- if (nodeList.hasTrailingComma) {
- write(",");
- }
- }
- function emitLinePreservingList(parent, nodes, allowTrailingComma, spacesBetweenBraces) {
- ts.Debug.assert(nodes.length > 0);
- increaseIndent();
- if (nodeStartPositionsAreOnSameLine(parent, nodes[0])) {
- if (spacesBetweenBraces) {
- write(" ");
- }
- }
- else {
- writeLine();
- }
- for (var i = 0, n = nodes.length; i < n; i++) {
- if (i) {
- if (nodeEndIsOnSameLineAsNodeStart(nodes[i - 1], nodes[i])) {
- write(", ");
- }
- else {
- write(",");
- writeLine();
- }
- }
- emit(nodes[i]);
- }
- if (nodes.hasTrailingComma && allowTrailingComma) {
- write(",");
- }
- decreaseIndent();
- if (nodeEndPositionsAreOnSameLine(parent, ts.lastOrUndefined(nodes))) {
- if (spacesBetweenBraces) {
- write(" ");
- }
- }
- else {
- writeLine();
- }
- }
- function emitList(nodes, start, count, multiLine, trailingComma, leadingComma, noTrailingNewLine, emitNode) {
- if (!emitNode) {
- emitNode = emit;
- }
- for (var i = 0; i < count; i++) {
- if (multiLine) {
- if (i || leadingComma) {
- write(",");
- }
- writeLine();
- }
- else {
- if (i || leadingComma) {
- write(", ");
- }
- }
- emitNode(nodes[start + i]);
- leadingComma = true;
- }
- if (trailingComma) {
- write(",");
- }
- if (multiLine && !noTrailingNewLine) {
- writeLine();
- }
- return count;
- }
- function emitCommaList(nodes) {
- if (nodes) {
- emitList(nodes, 0, nodes.length, false, false);
- }
- }
- function emitLines(nodes) {
- emitLinesStartingAt(nodes, 0);
- }
- function emitLinesStartingAt(nodes, startIndex) {
- for (var i = startIndex; i < nodes.length; i++) {
- writeLine();
- emit(nodes[i]);
- }
- }
- function isBinaryOrOctalIntegerLiteral(node, text) {
- if (node.kind === 7 /* NumericLiteral */ && text.length > 1) {
- switch (text.charCodeAt(1)) {
- case 98 /* b */:
- case 66 /* B */:
- case 111 /* o */:
- case 79 /* O */:
- return true;
- }
- }
- return false;
- }
- function emitLiteral(node) {
- var text = getLiteralText(node);
- if (compilerOptions.sourceMap && (node.kind === 8 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) {
- writer.writeLiteral(text);
- }
- else if (languageVersion < 2 /* ES6 */ && isBinaryOrOctalIntegerLiteral(node, text)) {
- write(node.text);
- }
- else {
- write(text);
- }
- }
- function getLiteralText(node) {
- // Any template literal or string literal with an extended escape
- // (e.g. "\u{0067}") will need to be downleveled as a escaped string literal.
- if (languageVersion < 2 /* ES6 */ && (ts.isTemplateLiteralKind(node.kind) || node.hasExtendedUnicodeEscape)) {
- return getQuotedEscapedLiteralText('"', node.text, '"');
- }
- // If we don't need to downlevel and we can reach the original source text using
- // the node's parent reference, then simply get the text as it was originally written.
- if (node.parent) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
- }
- // If we can't reach the original source text, use the canonical form if it's a number,
- // or an escaped quoted form of the original text if it's string-like.
- switch (node.kind) {
- case 8 /* StringLiteral */:
- return getQuotedEscapedLiteralText('"', node.text, '"');
- case 10 /* NoSubstitutionTemplateLiteral */:
- return getQuotedEscapedLiteralText('`', node.text, '`');
- case 11 /* TemplateHead */:
- return getQuotedEscapedLiteralText('`', node.text, '${');
- case 12 /* TemplateMiddle */:
- return getQuotedEscapedLiteralText('}', node.text, '${');
- case 13 /* TemplateTail */:
- return getQuotedEscapedLiteralText('}', node.text, '`');
- case 7 /* NumericLiteral */:
- return node.text;
- }
- ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for.");
- }
- function getQuotedEscapedLiteralText(leftQuote, text, rightQuote) {
- return leftQuote + ts.escapeNonAsciiCharacters(ts.escapeString(text)) + rightQuote;
- }
- function emitDownlevelRawTemplateLiteral(node) {
- // Find original source text, since we need to emit the raw strings of the tagged template.
- // The raw strings contain the (escaped) strings of what the user wrote.
- // Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
- var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
- // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
- // thus we need to remove those characters.
- // First template piece starts with "`", others with "}"
- // Last template piece ends with "`", others with "${"
- var isLast = node.kind === 10 /* NoSubstitutionTemplateLiteral */ || node.kind === 13 /* TemplateTail */;
- text = text.substring(1, text.length - (isLast ? 1 : 2));
- // Newline normalization:
- // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
- // and LineTerminatorSequences are normalized to for both TV and TRV.
- text = text.replace(/\r\n?/g, "\n");
- text = ts.escapeString(text);
- write('"' + text + '"');
- }
- function emitDownlevelTaggedTemplateArray(node, literalEmitter) {
- write("[");
- if (node.template.kind === 10 /* NoSubstitutionTemplateLiteral */) {
- literalEmitter(node.template);
- }
- else {
- literalEmitter(node.template.head);
- ts.forEach(node.template.templateSpans, function (child) {
- write(", ");
- literalEmitter(child.literal);
- });
- }
- write("]");
- }
- function emitDownlevelTaggedTemplate(node) {
- var tempVariable = createAndRecordTempVariable(0 /* Auto */);
- write("(");
- emit(tempVariable);
- write(" = ");
- emitDownlevelTaggedTemplateArray(node, emit);
- write(", ");
- emit(tempVariable);
- write(".raw = ");
- emitDownlevelTaggedTemplateArray(node, emitDownlevelRawTemplateLiteral);
- write(", ");
- emitParenthesizedIf(node.tag, needsParenthesisForPropertyAccessOrInvocation(node.tag));
- write("(");
- emit(tempVariable);
- // Now we emit the expressions
- if (node.template.kind === 171 /* TemplateExpression */) {
- ts.forEach(node.template.templateSpans, function (templateSpan) {
- write(", ");
- var needsParens = templateSpan.expression.kind === 169 /* BinaryExpression */
- && templateSpan.expression.operatorToken.kind === 23 /* CommaToken */;
- emitParenthesizedIf(templateSpan.expression, needsParens);
- });
- }
- write("))");
- }
- function emitTemplateExpression(node) {
- // In ES6 mode and above, we can simply emit each portion of a template in order, but in
- // ES3 & ES5 we must convert the template expression into a series of string concatenations.
- if (languageVersion >= 2 /* ES6 */) {
- ts.forEachChild(node, emit);
- return;
- }
- var emitOuterParens = ts.isExpression(node.parent)
- && templateNeedsParens(node, node.parent);
- if (emitOuterParens) {
- write("(");
- }
- var headEmitted = false;
- if (shouldEmitTemplateHead()) {
- emitLiteral(node.head);
- headEmitted = true;
- }
- for (var i = 0, n = node.templateSpans.length; i < n; i++) {
- var templateSpan = node.templateSpans[i];
- // Check if the expression has operands and binds its operands less closely than binary '+'.
- // If it does, we need to wrap the expression in parentheses. Otherwise, something like
- // `abc${ 1 << 2 }`
- // becomes
- // "abc" + 1 << 2 + ""
- // which is really
- // ("abc" + 1) << (2 + "")
- // rather than
- // "abc" + (1 << 2) + ""
- var needsParens = templateSpan.expression.kind !== 161 /* ParenthesizedExpression */
- && comparePrecedenceToBinaryPlus(templateSpan.expression) !== 1 /* GreaterThan */;
- if (i > 0 || headEmitted) {
- // If this is the first span and the head was not emitted, then this templateSpan's
- // expression will be the first to be emitted. Don't emit the preceding ' + ' in that
- // case.
- write(" + ");
- }
- emitParenthesizedIf(templateSpan.expression, needsParens);
- // Only emit if the literal is non-empty.
- // The binary '+' operator is left-associative, so the first string concatenation
- // with the head will force the result up to this point to be a string.
- // Emitting a '+ ""' has no semantic effect for middles and tails.
- if (templateSpan.literal.text.length !== 0) {
- write(" + ");
- emitLiteral(templateSpan.literal);
- }
- }
- if (emitOuterParens) {
- write(")");
- }
- function shouldEmitTemplateHead() {
- // If this expression has an empty head literal and the first template span has a non-empty
- // literal, then emitting the empty head literal is not necessary.
- // `${ foo } and ${ bar }`
- // can be emitted as
- // foo + " and " + bar
- // This is because it is only required that one of the first two operands in the emit
- // output must be a string literal, so that the other operand and all following operands
- // are forced into strings.
- //
- // If the first template span has an empty literal, then the head must still be emitted.
- // `${ foo }${ bar }`
- // must still be emitted as
- // "" + foo + bar
- // There is always atleast one templateSpan in this code path, since
- // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral()
- ts.Debug.assert(node.templateSpans.length !== 0);
- return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0;
- }
- function templateNeedsParens(template, parent) {
- switch (parent.kind) {
- case 157 /* CallExpression */:
- case 158 /* NewExpression */:
- return parent.expression === template;
- case 159 /* TaggedTemplateExpression */:
- case 161 /* ParenthesizedExpression */:
- return false;
- default:
- return comparePrecedenceToBinaryPlus(parent) !== -1 /* LessThan */;
- }
- }
- /**
- * Returns whether the expression has lesser, greater,
- * or equal precedence to the binary '+' operator
- */
- function comparePrecedenceToBinaryPlus(expression) {
- // All binary expressions have lower precedence than '+' apart from '*', '/', and '%'
- // which have greater precedence and '-' which has equal precedence.
- // All unary operators have a higher precedence apart from yield.
- // Arrow functions and conditionals have a lower precedence,
- // although we convert the former into regular function expressions in ES5 mode,
- // and in ES6 mode this function won't get called anyway.
- //
- // TODO (drosen): Note that we need to account for the upcoming 'yield' and
- // spread ('...') unary operators that are anticipated for ES6.
- switch (expression.kind) {
- case 169 /* BinaryExpression */:
- switch (expression.operatorToken.kind) {
- case 35 /* AsteriskToken */:
- case 36 /* SlashToken */:
- case 37 /* PercentToken */:
- return 1 /* GreaterThan */;
- case 33 /* PlusToken */:
- case 34 /* MinusToken */:
- return 0 /* EqualTo */;
- default:
- return -1 /* LessThan */;
- }
- case 172 /* YieldExpression */:
- case 170 /* ConditionalExpression */:
- return -1 /* LessThan */;
- default:
- return 1 /* GreaterThan */;
- }
- }
- }
- function emitTemplateSpan(span) {
- emit(span.expression);
- emit(span.literal);
- }
- // This function specifically handles numeric/string literals for enum and accessor 'identifiers'.
- // In a sense, it does not actually emit identifiers as much as it declares a name for a specific property.
- // For example, this is utilized when feeding in a result to Object.defineProperty.
- function emitExpressionForPropertyName(node) {
- ts.Debug.assert(node.kind !== 152 /* BindingElement */);
- if (node.kind === 8 /* StringLiteral */) {
- emitLiteral(node);
- }
- else if (node.kind === 127 /* ComputedPropertyName */) {
- // if this is a decorated computed property, we will need to capture the result
- // of the property expression so that we can apply decorators later. This is to ensure
- // we don't introduce unintended side effects:
- //
- // class C {
- // [_a = x]() { }
- // }
- //
- // The emit for the decorated computed property decorator is:
- //
- // Object.defineProperty(C.prototype, _a, __decorate([dec], C.prototype, _a, Object.getOwnPropertyDescriptor(C.prototype, _a)));
- //
- if (ts.nodeIsDecorated(node.parent)) {
- if (!computedPropertyNamesToGeneratedNames) {
- computedPropertyNamesToGeneratedNames = [];
- }
- var generatedName = computedPropertyNamesToGeneratedNames[ts.getNodeId(node)];
- if (generatedName) {
- // we have already generated a variable for this node, write that value instead.
- write(generatedName);
- return;
- }
- generatedName = createAndRecordTempVariable(0 /* Auto */).text;
- computedPropertyNamesToGeneratedNames[ts.getNodeId(node)] = generatedName;
- write(generatedName);
- write(" = ");
- }
- emit(node.expression);
- }
- else {
- write("\"");
- if (node.kind === 7 /* NumericLiteral */) {
- write(node.text);
- }
- else {
- writeTextOfNode(currentSourceFile, node);
- }
- write("\"");
- }
- }
- function isNotExpressionIdentifier(node) {
- var parent = node.parent;
- switch (parent.kind) {
- case 129 /* Parameter */:
- case 198 /* VariableDeclaration */:
- case 152 /* BindingElement */:
- case 132 /* PropertyDeclaration */:
- case 131 /* PropertySignature */:
- case 224 /* PropertyAssignment */:
- case 225 /* ShorthandPropertyAssignment */:
- case 226 /* EnumMember */:
- case 134 /* MethodDeclaration */:
- case 133 /* MethodSignature */:
- case 200 /* FunctionDeclaration */:
- case 136 /* GetAccessor */:
- case 137 /* SetAccessor */:
- case 162 /* FunctionExpression */:
- case 201 /* ClassDeclaration */:
- case 202 /* InterfaceDeclaration */:
- case 204 /* EnumDeclaration */:
- case 205 /* ModuleDeclaration */:
- case 208 /* ImportEqualsDeclaration */:
- case 210 /* ImportClause */:
- case 211 /* NamespaceImport */:
- return parent.name === node;
- case 213 /* ImportSpecifier */:
- case 217 /* ExportSpecifier */:
- return parent.name === node || parent.propertyName === node;
- case 190 /* BreakStatement */:
- case 189 /* ContinueStatement */:
- case 214 /* ExportAssignment */:
- return false;
- case 194 /* LabeledStatement */:
- return node.parent.label === node;
- }
- }
- function emitExpressionIdentifier(node) {
- var substitution = resolver.getExpressionNameSubstitution(node, getGeneratedNameForNode);
- if (substitution) {
- write(substitution);
- }
- else {
- writeTextOfNode(currentSourceFile, node);
- }
- }
- function getGeneratedNameForIdentifier(node) {
- if (ts.nodeIsSynthesized(node) || !blockScopedVariableToGeneratedName) {
- return undefined;
- }
- var variableId = resolver.getBlockScopedVariableId(node);
- if (variableId === undefined) {
- return undefined;
- }
- return blockScopedVariableToGeneratedName[variableId];
- }
- function emitIdentifier(node, allowGeneratedIdentifiers) {
- if (allowGeneratedIdentifiers) {
- var generatedName = getGeneratedNameForIdentifier(node);
- if (generatedName) {
- write(generatedName);
- return;
- }
- }
- if (!node.parent) {
- write(node.text);
- }
- else if (!isNotExpressionIdentifier(node)) {
- emitExpressionIdentifier(node);
- }
- else {
- writeTextOfNode(currentSourceFile, node);
- }
- }
- function emitThis(node) {
- if (resolver.getNodeCheckFlags(node) & 2 /* LexicalThis */) {
- write("_this");
- }
- else {
- write("this");
- }
- }
- function emitSuper(node) {
- if (languageVersion >= 2 /* ES6 */) {
- write("super");
- }
- else {
- var flags = resolver.getNodeCheckFlags(node);
- if (flags & 16 /* SuperInstance */) {
- write("_super.prototype");
- }
- else {
- write("_super");
- }
- }
- }
- function emitObjectBindingPattern(node) {
- write("{ ");
- var elements = node.elements;
- emitList(elements, 0, elements.length, false, elements.hasTrailingComma);
- write(" }");
- }
- function emitArrayBindingPattern(node) {
- write("[");
- var elements = node.elements;
- emitList(elements, 0, elements.length, false, elements.hasTrailingComma);
- write("]");
- }
- function emitBindingElement(node) {
- if (node.propertyName) {
- emit(node.propertyName, false);
- write(": ");
- }
- if (node.dotDotDotToken) {
- write("...");
- }
- if (ts.isBindingPattern(node.name)) {
- emit(node.name);
- }
- else {
- emitModuleMemberName(node);
- }
- emitOptional(" = ", node.initializer);
- }
- function emitSpreadElementExpression(node) {
- write("...");
- emit(node.expression);
- }
- function emitYieldExpression(node) {
- write(ts.tokenToString(110 /* YieldKeyword */));
- if (node.asteriskToken) {
- write("*");
- }
- if (node.expression) {
- write(" ");
- emit(node.expression);
- }
- }
- function needsParenthesisForPropertyAccessOrInvocation(node) {
- switch (node.kind) {
- case 65 /* Identifier */:
- case 153 /* ArrayLiteralExpression */:
- case 155 /* PropertyAccessExpression */:
- case 156 /* ElementAccessExpression */:
- case 157 /* CallExpression */:
- case 161 /* ParenthesizedExpression */:
- // This list is not exhaustive and only includes those cases that are relevant
- // to the check in emitArrayLiteral. More cases can be added as needed.
- return false;
- }
- return true;
- }
- function emitListWithSpread(elements, multiLine, trailingComma) {
- var pos = 0;
- var group = 0;
- var length = elements.length;
- while (pos < length) {
- // Emit using the pattern .concat(, , ...)
- if (group === 1) {
- write(".concat(");
- }
- else if (group > 1) {
- write(", ");
- }
- var e = elements[pos];
- if (e.kind === 173 /* SpreadElementExpression */) {
- e = e.expression;
- emitParenthesizedIf(e, group === 0 && needsParenthesisForPropertyAccessOrInvocation(e));
- pos++;
- }
- else {
- var i = pos;
- while (i < length && elements[i].kind !== 173 /* SpreadElementExpression */) {
- i++;
- }
- write("[");
- if (multiLine) {
- increaseIndent();
- }
- emitList(elements, pos, i - pos, multiLine, trailingComma && i === length);
- if (multiLine) {
- decreaseIndent();
- }
- write("]");
- pos = i;
- }
- group++;
- }
- if (group > 1) {
- write(")");
- }
- }
- function isSpreadElementExpression(node) {
- return node.kind === 173 /* SpreadElementExpression */;
- }
- function emitArrayLiteral(node) {
- var elements = node.elements;
- if (elements.length === 0) {
- write("[]");
- }
- else if (languageVersion >= 2 /* ES6 */ || !ts.forEach(elements, isSpreadElementExpression)) {
- write("[");
- emitLinePreservingList(node, node.elements, elements.hasTrailingComma, false);
- write("]");
- }
- else {
- emitListWithSpread(elements, (node.flags & 512 /* MultiLine */) !== 0,
- /*trailingComma*/ elements.hasTrailingComma);
- }
- }
- function emitObjectLiteralBody(node, numElements) {
- if (numElements === 0) {
- write("{}");
- return;
- }
- write("{");
- if (numElements > 0) {
- var properties = node.properties;
- // If we are not doing a downlevel transformation for object literals,
- // then try to preserve the original shape of the object literal.
- // Otherwise just try to preserve the formatting.
- if (numElements === properties.length) {
- emitLinePreservingList(node, properties, languageVersion >= 1 /* ES5 */, true);
- }
- else {
- var multiLine = (node.flags & 512 /* MultiLine */) !== 0;
- if (!multiLine) {
- write(" ");
- }
- else {
- increaseIndent();
- }
- emitList(properties, 0, numElements, multiLine, false);
- if (!multiLine) {
- write(" ");
- }
- else {
- decreaseIndent();
- }
- }
- }
- write("}");
- }
- function emitDownlevelObjectLiteralWithComputedProperties(node, firstComputedPropertyIndex) {
- var multiLine = (node.flags & 512 /* MultiLine */) !== 0;
- var properties = node.properties;
- write("(");
- if (multiLine) {
- increaseIndent();
- }
- // For computed properties, we need to create a unique handle to the object
- // literal so we can modify it without risking internal assignments tainting the object.
- var tempVar = createAndRecordTempVariable(0 /* Auto */);
- // Write out the first non-computed properties
- // (or all properties if none of them are computed),
- // then emit the rest through indexing on the temp variable.
- emit(tempVar);
- write(" = ");
- emitObjectLiteralBody(node, firstComputedPropertyIndex);
- for (var i = firstComputedPropertyIndex, n = properties.length; i < n; i++) {
- writeComma();
- var property = properties[i];
- emitStart(property);
- if (property.kind === 136 /* GetAccessor */ || property.kind === 137 /* SetAccessor */) {
- // TODO (drosen): Reconcile with 'emitMemberFunctions'.
- var accessors = ts.getAllAccessorDeclarations(node.properties, property);
- if (property !== accessors.firstAccessor) {
- continue;
- }
- write("Object.defineProperty(");
- emit(tempVar);
- write(", ");
- emitStart(node.name);
- emitExpressionForPropertyName(property.name);
- emitEnd(property.name);
- write(", {");
- increaseIndent();
- if (accessors.getAccessor) {
- writeLine();
- emitLeadingComments(accessors.getAccessor);
- write("get: ");
- emitStart(accessors.getAccessor);
- write("function ");
- emitSignatureAndBody(accessors.getAccessor);
- emitEnd(accessors.getAccessor);
- emitTrailingComments(accessors.getAccessor);
- write(",");
- }
- if (accessors.setAccessor) {
- writeLine();
- emitLeadingComments(accessors.setAccessor);
- write("set: ");
- emitStart(accessors.setAccessor);
- write("function ");
- emitSignatureAndBody(accessors.setAccessor);
- emitEnd(accessors.setAccessor);
- emitTrailingComments(accessors.setAccessor);
- write(",");
- }
- writeLine();
- write("enumerable: true,");
- writeLine();
- write("configurable: true");
- decreaseIndent();
- writeLine();
- write("})");
- emitEnd(property);
- }
- else {
- emitLeadingComments(property);
- emitStart(property.name);
- emit(tempVar);
- emitMemberAccessForPropertyName(property.name);
- emitEnd(property.name);
- write(" = ");
- if (property.kind === 224 /* PropertyAssignment */) {
- emit(property.initializer);
- }
- else if (property.kind === 225 /* ShorthandPropertyAssignment */) {
- emitExpressionIdentifier(property.name);
- }
- else if (property.kind === 134 /* MethodDeclaration */) {
- emitFunctionDeclaration(property);
- }
- else {
- ts.Debug.fail("ObjectLiteralElement type not accounted for: " + property.kind);
- }
- }
- emitEnd(property);
- }
- writeComma();
- emit(tempVar);
- if (multiLine) {
- decreaseIndent();
- writeLine();
- }
- write(")");
- function writeComma() {
- if (multiLine) {
- write(",");
- writeLine();
- }
- else {
- write(", ");
- }
- }
- }
- function emitObjectLiteral(node) {
- var properties = node.properties;
- if (languageVersion < 2 /* ES6 */) {
- var numProperties = properties.length;
- // Find the first computed property.
- // Everything until that point can be emitted as part of the initial object literal.
- var numInitialNonComputedProperties = numProperties;
- for (var i = 0, n = properties.length; i < n; i++) {
- if (properties[i].name.kind === 127 /* ComputedPropertyName */) {
- numInitialNonComputedProperties = i;
- break;
- }
- }
- var hasComputedProperty = numInitialNonComputedProperties !== properties.length;
- if (hasComputedProperty) {
- emitDownlevelObjectLiteralWithComputedProperties(node, numInitialNonComputedProperties);
- return;
- }
- }
- // Ordinary case: either the object has no computed properties
- // or we're compiling with an ES6+ target.
- emitObjectLiteralBody(node, properties.length);
- }
- function createBinaryExpression(left, operator, right, startsOnNewLine) {
- var result = ts.createSynthesizedNode(169 /* BinaryExpression */, startsOnNewLine);
- result.operatorToken = ts.createSynthesizedNode(operator);
- result.left = left;
- result.right = right;
- return result;
- }
- function createPropertyAccessExpression(expression, name) {
- var result = ts.createSynthesizedNode(155 /* PropertyAccessExpression */);
- result.expression = parenthesizeForAccess(expression);
- result.dotToken = ts.createSynthesizedNode(20 /* DotToken */);
- result.name = name;
- return result;
- }
- function createElementAccessExpression(expression, argumentExpression) {
- var result = ts.createSynthesizedNode(156 /* ElementAccessExpression */);
- result.expression = parenthesizeForAccess(expression);
- result.argumentExpression = argumentExpression;
- return result;
- }
- function parenthesizeForAccess(expr) {
- // isLeftHandSideExpression is almost the correct criterion for when it is not necessary
- // to parenthesize the expression before a dot. The known exceptions are:
- //
- // NewExpression:
- // new C.x -> not the same as (new C).x
- // NumberLiteral
- // 1.x -> not the same as (1).x
- //
- if (ts.isLeftHandSideExpression(expr) && expr.kind !== 158 /* NewExpression */ && expr.kind !== 7 /* NumericLiteral */) {
- return expr;
- }
- var node = ts.createSynthesizedNode(161 /* ParenthesizedExpression */);
- node.expression = expr;
- return node;
- }
- function emitComputedPropertyName(node) {
- write("[");
- emitExpressionForPropertyName(node);
- write("]");
- }
- function emitMethod(node) {
- if (languageVersion >= 2 /* ES6 */ && node.asteriskToken) {
- write("*");
- }
- emit(node.name, false);
- if (languageVersion < 2 /* ES6 */) {
- write(": function ");
- }
- emitSignatureAndBody(node);
- }
- function emitPropertyAssignment(node) {
- emit(node.name, false);
- write(": ");
- emit(node.initializer);
- }
- function emitShorthandPropertyAssignment(node) {
- emit(node.name, false);
- // If short-hand property has a prefix, then regardless of the target version, we will emit it as normal property assignment. For example:
- // module m {
- // export let y;
- // }
- // module m {
- // export let obj = { y };
- // }
- // The short-hand property in obj need to emit as such ... = { y : m.y } regardless of the TargetScript version
- if (languageVersion < 2 /* ES6 */) {
- // Emit identifier as an identifier
- write(": ");
- var generatedName = getGeneratedNameForIdentifier(node.name);
- if (generatedName) {
- write(generatedName);
- }
- else {
- // Even though this is stored as identifier treat it as an expression
- // Short-hand, { x }, is equivalent of normal form { x: x }
- emitExpressionIdentifier(node.name);
- }
- }
- else if (resolver.getExpressionNameSubstitution(node.name, getGeneratedNameForNode)) {
- // Emit identifier as an identifier
- write(": ");
- // Even though this is stored as identifier treat it as an expression
- // Short-hand, { x }, is equivalent of normal form { x: x }
- emitExpressionIdentifier(node.name);
- }
- }
- function tryEmitConstantValue(node) {
- if (compilerOptions.separateCompilation) {
- // do not inline enum values in separate compilation mode
- return false;
- }
- var constantValue = resolver.getConstantValue(node);
- if (constantValue !== undefined) {
- write(constantValue.toString());
- if (!compilerOptions.removeComments) {
- var propertyName = node.kind === 155 /* PropertyAccessExpression */ ? ts.declarationNameToString(node.name) : ts.getTextOfNode(node.argumentExpression);
- write(" /* " + propertyName + " */");
- }
- return true;
- }
- return false;
- }
- // Returns 'true' if the code was actually indented, false otherwise.
- // If the code is not indented, an optional valueToWriteWhenNotIndenting will be
- // emitted instead.
- function indentIfOnDifferentLines(parent, node1, node2, valueToWriteWhenNotIndenting) {
- var realNodesAreOnDifferentLines = !ts.nodeIsSynthesized(parent) && !nodeEndIsOnSameLineAsNodeStart(node1, node2);
- // Always use a newline for synthesized code if the synthesizer desires it.
- var synthesizedNodeIsOnDifferentLine = synthesizedNodeStartsOnNewLine(node2);
- if (realNodesAreOnDifferentLines || synthesizedNodeIsOnDifferentLine) {
- increaseIndent();
- writeLine();
- return true;
- }
- else {
- if (valueToWriteWhenNotIndenting) {
- write(valueToWriteWhenNotIndenting);
- }
- return false;
- }
- }
- function emitPropertyAccess(node) {
- if (tryEmitConstantValue(node)) {
- return;
- }
- emit(node.expression);
- var indentedBeforeDot = indentIfOnDifferentLines(node, node.expression, node.dotToken);
- write(".");
- var indentedAfterDot = indentIfOnDifferentLines(node, node.dotToken, node.name);
- emit(node.name, false);
- decreaseIndentIf(indentedBeforeDot, indentedAfterDot);
- }
- function emitQualifiedName(node) {
- emit(node.left);
- write(".");
- emit(node.right);
- }
- function emitIndexedAccess(node) {
- if (tryEmitConstantValue(node)) {
- return;
- }
- emit(node.expression);
- write("[");
- emit(node.argumentExpression);
- write("]");
- }
- function hasSpreadElement(elements) {
- return ts.forEach(elements, function (e) { return e.kind === 173 /* SpreadElementExpression */; });
- }
- function skipParentheses(node) {
- while (node.kind === 161 /* ParenthesizedExpression */ || node.kind === 160 /* TypeAssertionExpression */) {
- node = node.expression;
- }
- return node;
- }
- function emitCallTarget(node) {
- if (node.kind === 65 /* Identifier */ || node.kind === 93 /* ThisKeyword */ || node.kind === 91 /* SuperKeyword */) {
- emit(node);
- return node;
- }
- var temp = createAndRecordTempVariable(0 /* Auto */);
- write("(");
- emit(temp);
- write(" = ");
- emit(node);
- write(")");
- return temp;
- }
- function emitCallWithSpread(node) {
- var target;
- var expr = skipParentheses(node.expression);
- if (expr.kind === 155 /* PropertyAccessExpression */) {
- // Target will be emitted as "this" argument
- target = emitCallTarget(expr.expression);
- write(".");
- emit(expr.name);
- }
- else if (expr.kind === 156 /* ElementAccessExpression */) {
- // Target will be emitted as "this" argument
- target = emitCallTarget(expr.expression);
- write("[");
- emit(expr.argumentExpression);
- write("]");
- }
- else if (expr.kind === 91 /* SuperKeyword */) {
- target = expr;
- write("_super");
- }
- else {
- emit(node.expression);
- }
- write(".apply(");
- if (target) {
- if (target.kind === 91 /* SuperKeyword */) {
- // Calls of form super(...) and super.foo(...)
- emitThis(target);
- }
- else {
- // Calls of form obj.foo(...)
- emit(target);
- }
- }
- else {
- // Calls of form foo(...)
- write("void 0");
- }
- write(", ");
- emitListWithSpread(node.arguments, false, false);
- write(")");
- }
- function emitCallExpression(node) {
- if (languageVersion < 2 /* ES6 */ && hasSpreadElement(node.arguments)) {
- emitCallWithSpread(node);
- return;
- }
- var superCall = false;
- if (node.expression.kind === 91 /* SuperKeyword */) {
- emitSuper(node.expression);
- superCall = true;
- }
- else {
- emit(node.expression);
- superCall = node.expression.kind === 155 /* PropertyAccessExpression */ && node.expression.expression.kind === 91 /* SuperKeyword */;
- }
- if (superCall && languageVersion < 2 /* ES6 */) {
- write(".call(");
- emitThis(node.expression);
- if (node.arguments.length) {
- write(", ");
- emitCommaList(node.arguments);
- }
- write(")");
- }
- else {
- write("(");
- emitCommaList(node.arguments);
- write(")");
- }
- }
- function emitNewExpression(node) {
- write("new ");
- emit(node.expression);
- if (node.arguments) {
- write("(");
- emitCommaList(node.arguments);
- write(")");
- }
- }
- function emitTaggedTemplateExpression(node) {
- if (languageVersion >= 2 /* ES6 */) {
- emit(node.tag);
- write(" ");
- emit(node.template);
- }
- else {
- emitDownlevelTaggedTemplate(node);
- }
- }
- function emitParenExpression(node) {
- if (!node.parent || node.parent.kind !== 163 /* ArrowFunction */) {
- if (node.expression.kind === 160 /* TypeAssertionExpression */) {
- var operand = node.expression.expression;
- // Make sure we consider all nested cast expressions, e.g.:
- // (-A).x;
- while (operand.kind == 160 /* TypeAssertionExpression */) {
- operand = operand.expression;
- }
- // We have an expression of the form: (SubExpr)
- // Emitting this as (SubExpr) is really not desirable. We would like to emit the subexpr as is.
- // Omitting the parentheses, however, could cause change in the semantics of the generated
- // code if the casted expression has a lower precedence than the rest of the expression, e.g.:
- // (new A).foo should be emitted as (new A).foo and not new A.foo
- // (typeof A).toString() should be emitted as (typeof A).toString() and not typeof A.toString()
- // new (A()) should be emitted as new (A()) and not new A()
- // (function foo() { })() should be emitted as an IIF (function foo(){})() and not declaration function foo(){} ()
- if (operand.kind !== 167 /* PrefixUnaryExpression */ &&
- operand.kind !== 166 /* VoidExpression */ &&
- operand.kind !== 165 /* TypeOfExpression */ &&
- operand.kind !== 164 /* DeleteExpression */ &&
- operand.kind !== 168 /* PostfixUnaryExpression */ &&
- operand.kind !== 158 /* NewExpression */ &&
- !(operand.kind === 157 /* CallExpression */ && node.parent.kind === 158 /* NewExpression */) &&
- !(operand.kind === 162 /* FunctionExpression */ && node.parent.kind === 157 /* CallExpression */)) {
- emit(operand);
- return;
- }
- }
- }
- write("(");
- emit(node.expression);
- write(")");
- }
- function emitDeleteExpression(node) {
- write(ts.tokenToString(74 /* DeleteKeyword */));
- write(" ");
- emit(node.expression);
- }
- function emitVoidExpression(node) {
- write(ts.tokenToString(99 /* VoidKeyword */));
- write(" ");
- emit(node.expression);
- }
- function emitTypeOfExpression(node) {
- write(ts.tokenToString(97 /* TypeOfKeyword */));
- write(" ");
- emit(node.expression);
- }
- function isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node) {
- if (!isCurrentFileSystemExternalModule() || node.kind !== 65 /* Identifier */ || ts.nodeIsSynthesized(node)) {
- return false;
- }
- var isVariableDeclarationOrBindingElement = node.parent && (node.parent.kind === 198 /* VariableDeclaration */ || node.parent.kind === 152 /* BindingElement */);
- var targetDeclaration = isVariableDeclarationOrBindingElement
- ? node.parent
- : resolver.getReferencedValueDeclaration(node);
- return isSourceFileLevelDeclarationInSystemExternalModule(targetDeclaration, true);
- }
- function emitPrefixUnaryExpression(node) {
- var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
- if (exportChanged) {
- // emit
- // ++x
- // as
- // exports('x', ++x)
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(node.operand);
- write("\", ");
- }
- write(ts.tokenToString(node.operator));
- // In some cases, we need to emit a space between the operator and the operand. One obvious case
- // is when the operator is an identifier, like delete or typeof. We also need to do this for plus
- // and minus expressions in certain cases. Specifically, consider the following two cases (parens
- // are just for clarity of exposition, and not part of the source code):
- //
- // (+(+1))
- // (+(++1))
- //
- // We need to emit a space in both cases. In the first case, the absence of a space will make
- // the resulting expression a prefix increment operation. And in the second, it will make the resulting
- // expression a prefix increment whose operand is a plus expression - (++(+x))
- // The same is true of minus of course.
- if (node.operand.kind === 167 /* PrefixUnaryExpression */) {
- var operand = node.operand;
- if (node.operator === 33 /* PlusToken */ && (operand.operator === 33 /* PlusToken */ || operand.operator === 38 /* PlusPlusToken */)) {
- write(" ");
- }
- else if (node.operator === 34 /* MinusToken */ && (operand.operator === 34 /* MinusToken */ || operand.operator === 39 /* MinusMinusToken */)) {
- write(" ");
- }
- }
- emit(node.operand);
- if (exportChanged) {
- write(")");
- }
- }
- function emitPostfixUnaryExpression(node) {
- var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.operand);
- if (exportChanged) {
- // export function returns the value that was passes as the second argument
- // however for postfix unary expressions result value should be the value before modification.
- // emit 'x++' as '(export('x', ++x) - 1)' and 'x--' as '(export('x', --x) + 1)'
- write("(" + exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(node.operand);
- write("\", ");
- write(ts.tokenToString(node.operator));
- emit(node.operand);
- if (node.operator === 38 /* PlusPlusToken */) {
- write(") - 1)");
- }
- else {
- write(") + 1)");
- }
- }
- else {
- emit(node.operand);
- write(ts.tokenToString(node.operator));
- }
- }
- /*
- * Checks if given node is a source file level declaration (not nested in module/function).
- * If 'isExported' is true - then declaration must also be exported.
- * This function is used in two cases:
- * - check if node is a exported source file level value to determine
- * if we should also export the value after its it changed
- * - check if node is a source level declaration to emit it differently,
- * i.e non-exported variable statement 'var x = 1' is hoisted so
- * we we emit variable statement 'var' should be dropped.
- */
- function isSourceFileLevelDeclarationInSystemExternalModule(node, isExported) {
- if (!node || languageVersion >= 2 /* ES6 */ || !isCurrentFileSystemExternalModule()) {
- return false;
- }
- var current = node;
- while (current) {
- if (current.kind === 227 /* SourceFile */) {
- return !isExported || ((ts.getCombinedNodeFlags(node) & 1 /* Export */) !== 0);
- }
- else if (ts.isFunctionLike(current) || current.kind === 206 /* ModuleBlock */) {
- return false;
- }
- else {
- current = current.parent;
- }
- }
- }
- function emitBinaryExpression(node) {
- if (languageVersion < 2 /* ES6 */ && node.operatorToken.kind === 53 /* EqualsToken */ &&
- (node.left.kind === 154 /* ObjectLiteralExpression */ || node.left.kind === 153 /* ArrayLiteralExpression */)) {
- emitDestructuring(node, node.parent.kind === 182 /* ExpressionStatement */);
- }
- else {
- var exportChanged = node.operatorToken.kind >= 53 /* FirstAssignment */ &&
- node.operatorToken.kind <= 64 /* LastAssignment */ &&
- isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.left);
- if (exportChanged) {
- // emit assignment 'x y' as 'exports("x", x y)'
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(node.left);
- write("\", ");
- }
- emit(node.left);
- var indentedBeforeOperator = indentIfOnDifferentLines(node, node.left, node.operatorToken, node.operatorToken.kind !== 23 /* CommaToken */ ? " " : undefined);
- write(ts.tokenToString(node.operatorToken.kind));
- var indentedAfterOperator = indentIfOnDifferentLines(node, node.operatorToken, node.right, " ");
- emit(node.right);
- decreaseIndentIf(indentedBeforeOperator, indentedAfterOperator);
- if (exportChanged) {
- write(")");
- }
- }
- }
- function synthesizedNodeStartsOnNewLine(node) {
- return ts.nodeIsSynthesized(node) && node.startsOnNewLine;
- }
- function emitConditionalExpression(node) {
- emit(node.condition);
- var indentedBeforeQuestion = indentIfOnDifferentLines(node, node.condition, node.questionToken, " ");
- write("?");
- var indentedAfterQuestion = indentIfOnDifferentLines(node, node.questionToken, node.whenTrue, " ");
- emit(node.whenTrue);
- decreaseIndentIf(indentedBeforeQuestion, indentedAfterQuestion);
- var indentedBeforeColon = indentIfOnDifferentLines(node, node.whenTrue, node.colonToken, " ");
- write(":");
- var indentedAfterColon = indentIfOnDifferentLines(node, node.colonToken, node.whenFalse, " ");
- emit(node.whenFalse);
- decreaseIndentIf(indentedBeforeColon, indentedAfterColon);
- }
- // Helper function to decrease the indent if we previously indented. Allows multiple
- // previous indent values to be considered at a time. This also allows caller to just
- // call this once, passing in all their appropriate indent values, instead of needing
- // to call this helper function multiple times.
- function decreaseIndentIf(value1, value2) {
- if (value1) {
- decreaseIndent();
- }
- if (value2) {
- decreaseIndent();
- }
- }
- function isSingleLineEmptyBlock(node) {
- if (node && node.kind === 179 /* Block */) {
- var block = node;
- return block.statements.length === 0 && nodeEndIsOnSameLineAsNodeStart(block, block);
- }
- }
- function emitBlock(node) {
- if (isSingleLineEmptyBlock(node)) {
- emitToken(14 /* OpenBraceToken */, node.pos);
- write(" ");
- emitToken(15 /* CloseBraceToken */, node.statements.end);
- return;
- }
- emitToken(14 /* OpenBraceToken */, node.pos);
- increaseIndent();
- scopeEmitStart(node.parent);
- if (node.kind === 206 /* ModuleBlock */) {
- ts.Debug.assert(node.parent.kind === 205 /* ModuleDeclaration */);
- emitCaptureThisForNodeIfNecessary(node.parent);
- }
- emitLines(node.statements);
- if (node.kind === 206 /* ModuleBlock */) {
- emitTempDeclarations(true);
- }
- decreaseIndent();
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.statements.end);
- scopeEmitEnd();
- }
- function emitEmbeddedStatement(node) {
- if (node.kind === 179 /* Block */) {
- write(" ");
- emit(node);
- }
- else {
- increaseIndent();
- writeLine();
- emit(node);
- decreaseIndent();
- }
- }
- function emitExpressionStatement(node) {
- emitParenthesizedIf(node.expression, node.expression.kind === 163 /* ArrowFunction */);
- write(";");
- }
- function emitIfStatement(node) {
- var endPos = emitToken(84 /* IfKeyword */, node.pos);
- write(" ");
- endPos = emitToken(16 /* OpenParenToken */, endPos);
- emit(node.expression);
- emitToken(17 /* CloseParenToken */, node.expression.end);
- emitEmbeddedStatement(node.thenStatement);
- if (node.elseStatement) {
- writeLine();
- emitToken(76 /* ElseKeyword */, node.thenStatement.end);
- if (node.elseStatement.kind === 183 /* IfStatement */) {
- write(" ");
- emit(node.elseStatement);
- }
- else {
- emitEmbeddedStatement(node.elseStatement);
- }
- }
- }
- function emitDoStatement(node) {
- write("do");
- emitEmbeddedStatement(node.statement);
- if (node.statement.kind === 179 /* Block */) {
- write(" ");
- }
- else {
- writeLine();
- }
- write("while (");
- emit(node.expression);
- write(");");
- }
- function emitWhileStatement(node) {
- write("while (");
- emit(node.expression);
- write(")");
- emitEmbeddedStatement(node.statement);
- }
- /* Returns true if start of variable declaration list was emitted.
- * Return false if nothing was written - this can happen for source file level variable declarations
- * in system modules - such variable declarations are hoisted.
- */
- function tryEmitStartOfVariableDeclarationList(decl, startPos) {
- if (shouldHoistVariable(decl, true)) {
- // variables in variable declaration list were already hoisted
- return false;
- }
- var tokenKind = 98 /* VarKeyword */;
- if (decl && languageVersion >= 2 /* ES6 */) {
- if (ts.isLet(decl)) {
- tokenKind = 104 /* LetKeyword */;
- }
- else if (ts.isConst(decl)) {
- tokenKind = 70 /* ConstKeyword */;
- }
- }
- if (startPos !== undefined) {
- emitToken(tokenKind, startPos);
- write(" ");
- }
- else {
- switch (tokenKind) {
- case 98 /* VarKeyword */:
- write("var ");
- break;
- case 104 /* LetKeyword */:
- write("let ");
- break;
- case 70 /* ConstKeyword */:
- write("const ");
- break;
- }
- }
- return true;
- }
- function emitVariableDeclarationListSkippingUninitializedEntries(list) {
- var started = false;
- for (var _i = 0, _a = list.declarations; _i < _a.length; _i++) {
- var decl = _a[_i];
- if (!decl.initializer) {
- continue;
- }
- if (!started) {
- started = true;
- }
- else {
- write(", ");
- }
- emit(decl);
- }
- return started;
- }
- function emitForStatement(node) {
- var endPos = emitToken(82 /* ForKeyword */, node.pos);
- write(" ");
- endPos = emitToken(16 /* OpenParenToken */, endPos);
- if (node.initializer && node.initializer.kind === 199 /* VariableDeclarationList */) {
- var variableDeclarationList = node.initializer;
- var startIsEmitted = tryEmitStartOfVariableDeclarationList(variableDeclarationList, endPos);
- if (startIsEmitted) {
- emitCommaList(variableDeclarationList.declarations);
- }
- else {
- emitVariableDeclarationListSkippingUninitializedEntries(variableDeclarationList);
- }
- }
- else if (node.initializer) {
- emit(node.initializer);
- }
- write(";");
- emitOptional(" ", node.condition);
- write(";");
- emitOptional(" ", node.iterator);
- write(")");
- emitEmbeddedStatement(node.statement);
- }
- function emitForInOrForOfStatement(node) {
- if (languageVersion < 2 /* ES6 */ && node.kind === 188 /* ForOfStatement */) {
- return emitDownLevelForOfStatement(node);
- }
- var endPos = emitToken(82 /* ForKeyword */, node.pos);
- write(" ");
- endPos = emitToken(16 /* OpenParenToken */, endPos);
- if (node.initializer.kind === 199 /* VariableDeclarationList */) {
- var variableDeclarationList = node.initializer;
- if (variableDeclarationList.declarations.length >= 1) {
- tryEmitStartOfVariableDeclarationList(variableDeclarationList, endPos);
- emit(variableDeclarationList.declarations[0]);
- }
- }
- else {
- emit(node.initializer);
- }
- if (node.kind === 187 /* ForInStatement */) {
- write(" in ");
- }
- else {
- write(" of ");
- }
- emit(node.expression);
- emitToken(17 /* CloseParenToken */, node.expression.end);
- emitEmbeddedStatement(node.statement);
- }
- function emitDownLevelForOfStatement(node) {
- // The following ES6 code:
- //
- // for (let v of expr) { }
- //
- // should be emitted as
- //
- // for (let _i = 0, _a = expr; _i < _a.length; _i++) {
- // let v = _a[_i];
- // }
- //
- // where _a and _i are temps emitted to capture the RHS and the counter,
- // respectively.
- // When the left hand side is an expression instead of a let declaration,
- // the "let v" is not emitted.
- // When the left hand side is a let/const, the v is renamed if there is
- // another v in scope.
- // Note that all assignments to the LHS are emitted in the body, including
- // all destructuring.
- // Note also that because an extra statement is needed to assign to the LHS,
- // for-of bodies are always emitted as blocks.
- var endPos = emitToken(82 /* ForKeyword */, node.pos);
- write(" ");
- endPos = emitToken(16 /* OpenParenToken */, endPos);
- // Do not emit the LHS let declaration yet, because it might contain destructuring.
- // Do not call recordTempDeclaration because we are declaring the temps
- // right here. Recording means they will be declared later.
- // In the case where the user wrote an identifier as the RHS, like this:
- //
- // for (let v of arr) { }
- //
- // we don't want to emit a temporary variable for the RHS, just use it directly.
- var rhsIsIdentifier = node.expression.kind === 65 /* Identifier */;
- var counter = createTempVariable(268435456 /* _i */);
- var rhsReference = rhsIsIdentifier ? node.expression : createTempVariable(0 /* Auto */);
- // This is the let keyword for the counter and rhsReference. The let keyword for
- // the LHS will be emitted inside the body.
- emitStart(node.expression);
- write("var ");
- // _i = 0
- emitNodeWithoutSourceMap(counter);
- write(" = 0");
- emitEnd(node.expression);
- if (!rhsIsIdentifier) {
- // , _a = expr
- write(", ");
- emitStart(node.expression);
- emitNodeWithoutSourceMap(rhsReference);
- write(" = ");
- emitNodeWithoutSourceMap(node.expression);
- emitEnd(node.expression);
- }
- write("; ");
- // _i < _a.length;
- emitStart(node.initializer);
- emitNodeWithoutSourceMap(counter);
- write(" < ");
- emitNodeWithoutSourceMap(rhsReference);
- write(".length");
- emitEnd(node.initializer);
- write("; ");
- // _i++)
- emitStart(node.initializer);
- emitNodeWithoutSourceMap(counter);
- write("++");
- emitEnd(node.initializer);
- emitToken(17 /* CloseParenToken */, node.expression.end);
- // Body
- write(" {");
- writeLine();
- increaseIndent();
- // Initialize LHS
- // let v = _a[_i];
- var rhsIterationValue = createElementAccessExpression(rhsReference, counter);
- emitStart(node.initializer);
- if (node.initializer.kind === 199 /* VariableDeclarationList */) {
- write("var ");
- var variableDeclarationList = node.initializer;
- if (variableDeclarationList.declarations.length > 0) {
- var declaration = variableDeclarationList.declarations[0];
- if (ts.isBindingPattern(declaration.name)) {
- // This works whether the declaration is a var, let, or const.
- // It will use rhsIterationValue _a[_i] as the initializer.
- emitDestructuring(declaration, false, rhsIterationValue);
- }
- else {
- // The following call does not include the initializer, so we have
- // to emit it separately.
- emitNodeWithoutSourceMap(declaration);
- write(" = ");
- emitNodeWithoutSourceMap(rhsIterationValue);
- }
- }
- else {
- // It's an empty declaration list. This can only happen in an error case, if the user wrote
- // for (let of []) {}
- emitNodeWithoutSourceMap(createTempVariable(0 /* Auto */));
- write(" = ");
- emitNodeWithoutSourceMap(rhsIterationValue);
- }
- }
- else {
- // Initializer is an expression. Emit the expression in the body, so that it's
- // evaluated on every iteration.
- var assignmentExpression = createBinaryExpression(node.initializer, 53 /* EqualsToken */, rhsIterationValue, false);
- if (node.initializer.kind === 153 /* ArrayLiteralExpression */ || node.initializer.kind === 154 /* ObjectLiteralExpression */) {
- // This is a destructuring pattern, so call emitDestructuring instead of emit. Calling emit will not work, because it will cause
- // the BinaryExpression to be passed in instead of the expression statement, which will cause emitDestructuring to crash.
- emitDestructuring(assignmentExpression, true, undefined);
- }
- else {
- emitNodeWithoutSourceMap(assignmentExpression);
- }
- }
- emitEnd(node.initializer);
- write(";");
- if (node.statement.kind === 179 /* Block */) {
- emitLines(node.statement.statements);
- }
- else {
- writeLine();
- emit(node.statement);
- }
- writeLine();
- decreaseIndent();
- write("}");
- }
- function emitBreakOrContinueStatement(node) {
- emitToken(node.kind === 190 /* BreakStatement */ ? 66 /* BreakKeyword */ : 71 /* ContinueKeyword */, node.pos);
- emitOptional(" ", node.label);
- write(";");
- }
- function emitReturnStatement(node) {
- emitToken(90 /* ReturnKeyword */, node.pos);
- emitOptional(" ", node.expression);
- write(";");
- }
- function emitWithStatement(node) {
- write("with (");
- emit(node.expression);
- write(")");
- emitEmbeddedStatement(node.statement);
- }
- function emitSwitchStatement(node) {
- var endPos = emitToken(92 /* SwitchKeyword */, node.pos);
- write(" ");
- emitToken(16 /* OpenParenToken */, endPos);
- emit(node.expression);
- endPos = emitToken(17 /* CloseParenToken */, node.expression.end);
- write(" ");
- emitCaseBlock(node.caseBlock, endPos);
- }
- function emitCaseBlock(node, startPos) {
- emitToken(14 /* OpenBraceToken */, startPos);
- increaseIndent();
- emitLines(node.clauses);
- decreaseIndent();
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.clauses.end);
- }
- function nodeStartPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node1.pos)) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
- }
- function nodeEndPositionsAreOnSameLine(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, node2.end);
- }
- function nodeEndIsOnSameLineAsNodeStart(node1, node2) {
- return ts.getLineOfLocalPosition(currentSourceFile, node1.end) ===
- ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node2.pos));
- }
- function emitCaseOrDefaultClause(node) {
- if (node.kind === 220 /* CaseClause */) {
- write("case ");
- emit(node.expression);
- write(":");
- }
- else {
- write("default:");
- }
- if (node.statements.length === 1 && nodeStartPositionsAreOnSameLine(node, node.statements[0])) {
- write(" ");
- emit(node.statements[0]);
- }
- else {
- increaseIndent();
- emitLines(node.statements);
- decreaseIndent();
- }
- }
- function emitThrowStatement(node) {
- write("throw ");
- emit(node.expression);
- write(";");
- }
- function emitTryStatement(node) {
- write("try ");
- emit(node.tryBlock);
- emit(node.catchClause);
- if (node.finallyBlock) {
- writeLine();
- write("finally ");
- emit(node.finallyBlock);
- }
- }
- function emitCatchClause(node) {
- writeLine();
- var endPos = emitToken(68 /* CatchKeyword */, node.pos);
- write(" ");
- emitToken(16 /* OpenParenToken */, endPos);
- emit(node.variableDeclaration);
- emitToken(17 /* CloseParenToken */, node.variableDeclaration ? node.variableDeclaration.end : endPos);
- write(" ");
- emitBlock(node.block);
- }
- function emitDebuggerStatement(node) {
- emitToken(72 /* DebuggerKeyword */, node.pos);
- write(";");
- }
- function emitLabelledStatement(node) {
- emit(node.label);
- write(": ");
- emit(node.statement);
- }
- function getContainingModule(node) {
- do {
- node = node.parent;
- } while (node && node.kind !== 205 /* ModuleDeclaration */);
- return node;
- }
- function emitContainingModuleName(node) {
- var container = getContainingModule(node);
- write(container ? getGeneratedNameForNode(container) : "exports");
- }
- function emitModuleMemberName(node) {
- emitStart(node.name);
- if (ts.getCombinedNodeFlags(node) & 1 /* Export */) {
- var container = getContainingModule(node);
- if (container) {
- write(getGeneratedNameForNode(container));
- write(".");
- }
- else if (languageVersion < 2 /* ES6 */ && compilerOptions.module !== 3 /* System */) {
- write("exports.");
- }
- }
- emitNodeWithoutSourceMap(node.name);
- emitEnd(node.name);
- }
- function createVoidZero() {
- var zero = ts.createSynthesizedNode(7 /* NumericLiteral */);
- zero.text = "0";
- var result = ts.createSynthesizedNode(166 /* VoidExpression */);
- result.expression = zero;
- return result;
- }
- function emitExportMemberAssignment(node) {
- if (node.flags & 1 /* Export */) {
- writeLine();
- emitStart(node);
- if (compilerOptions.module === 3 /* System */) {
- // emit export default as
- // export("default", )
- write(exportFunctionForFile + "(\"");
- if (node.flags & 256 /* Default */) {
- write("default");
- }
- else {
- emitNodeWithoutSourceMap(node.name);
- }
- write("\", ");
- emitDeclarationName(node);
- write(")");
- }
- else {
- if (node.flags & 256 /* Default */) {
- if (languageVersion === 0 /* ES3 */) {
- write("exports[\"default\"]");
- }
- else {
- write("exports.default");
- }
- }
- else {
- emitModuleMemberName(node);
- }
- write(" = ");
- emitDeclarationName(node);
- }
- emitEnd(node);
- write(";");
- }
- }
- function emitExportMemberAssignments(name) {
- if (!exportEquals && exportSpecifiers && ts.hasProperty(exportSpecifiers, name.text)) {
- for (var _i = 0, _a = exportSpecifiers[name.text]; _i < _a.length; _i++) {
- var specifier = _a[_i];
- writeLine();
- emitStart(specifier.name);
- if (compilerOptions.module === 3 /* System */) {
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(specifier.name);
- write("\", ");
- emitExpressionIdentifier(name);
- write(")");
- }
- else {
- emitContainingModuleName(specifier);
- write(".");
- emitNodeWithoutSourceMap(specifier.name);
- emitEnd(specifier.name);
- write(" = ");
- emitExpressionIdentifier(name);
- }
- write(";");
- }
- }
- }
- function emitDestructuring(root, isAssignmentExpressionStatement, value) {
- var emitCount = 0;
- // An exported declaration is actually emitted as an assignment (to a property on the module object), so
- // temporary variables in an exported declaration need to have real declarations elsewhere
- // Also temporary variables should be explicitly allocated for source level declarations when module target is system
- // because actual variable declarations are hoisted
- var canDefineTempVariablesInPlace = false;
- if (root.kind === 198 /* VariableDeclaration */) {
- var isExported = ts.getCombinedNodeFlags(root) & 1 /* Export */;
- var isSourceLevelForSystemModuleKind = isSourceFileLevelDeclarationInSystemExternalModule(root, false);
- canDefineTempVariablesInPlace = !isExported && !isSourceLevelForSystemModuleKind;
- }
- else if (root.kind === 129 /* Parameter */) {
- canDefineTempVariablesInPlace = true;
- }
- if (root.kind === 169 /* BinaryExpression */) {
- emitAssignmentExpression(root);
- }
- else {
- ts.Debug.assert(!isAssignmentExpressionStatement);
- emitBindingElement(root, value);
- }
- function emitAssignment(name, value) {
- if (emitCount++) {
- write(", ");
- }
- renameNonTopLevelLetAndConst(name);
- var isVariableDeclarationOrBindingElement = name.parent && (name.parent.kind === 198 /* VariableDeclaration */ || name.parent.kind === 152 /* BindingElement */);
- var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(name);
- if (exportChanged) {
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(name);
- write("\", ");
- }
- if (isVariableDeclarationOrBindingElement) {
- emitModuleMemberName(name.parent);
- }
- else {
- emit(name);
- }
- write(" = ");
- emit(value);
- if (exportChanged) {
- write(")");
- }
- }
- function ensureIdentifier(expr) {
- if (expr.kind !== 65 /* Identifier */) {
- var identifier = createTempVariable(0 /* Auto */);
- if (!canDefineTempVariablesInPlace) {
- recordTempDeclaration(identifier);
- }
- emitAssignment(identifier, expr);
- expr = identifier;
- }
- return expr;
- }
- function createDefaultValueCheck(value, defaultValue) {
- // The value expression will be evaluated twice, so for anything but a simple identifier
- // we need to generate a temporary variable
- value = ensureIdentifier(value);
- // Return the expression 'value === void 0 ? defaultValue : value'
- var equals = ts.createSynthesizedNode(169 /* BinaryExpression */);
- equals.left = value;
- equals.operatorToken = ts.createSynthesizedNode(30 /* EqualsEqualsEqualsToken */);
- equals.right = createVoidZero();
- return createConditionalExpression(equals, defaultValue, value);
- }
- function createConditionalExpression(condition, whenTrue, whenFalse) {
- var cond = ts.createSynthesizedNode(170 /* ConditionalExpression */);
- cond.condition = condition;
- cond.questionToken = ts.createSynthesizedNode(50 /* QuestionToken */);
- cond.whenTrue = whenTrue;
- cond.colonToken = ts.createSynthesizedNode(51 /* ColonToken */);
- cond.whenFalse = whenFalse;
- return cond;
- }
- function createNumericLiteral(value) {
- var node = ts.createSynthesizedNode(7 /* NumericLiteral */);
- node.text = "" + value;
- return node;
- }
- function createPropertyAccessForDestructuringProperty(object, propName) {
- if (propName.kind !== 65 /* Identifier */) {
- return createElementAccessExpression(object, propName);
- }
- return createPropertyAccessExpression(object, propName);
- }
- function createSliceCall(value, sliceIndex) {
- var call = ts.createSynthesizedNode(157 /* CallExpression */);
- var sliceIdentifier = ts.createSynthesizedNode(65 /* Identifier */);
- sliceIdentifier.text = "slice";
- call.expression = createPropertyAccessExpression(value, sliceIdentifier);
- call.arguments = ts.createSynthesizedNodeArray();
- call.arguments[0] = createNumericLiteral(sliceIndex);
- return call;
- }
- function emitObjectLiteralAssignment(target, value) {
- var properties = target.properties;
- if (properties.length !== 1) {
- // For anything but a single element destructuring we need to generate a temporary
- // to ensure value is evaluated exactly once.
- value = ensureIdentifier(value);
- }
- for (var _i = 0; _i < properties.length; _i++) {
- var p = properties[_i];
- if (p.kind === 224 /* PropertyAssignment */ || p.kind === 225 /* ShorthandPropertyAssignment */) {
- // TODO(andersh): Computed property support
- var propName = (p.name);
- emitDestructuringAssignment(p.initializer || propName, createPropertyAccessForDestructuringProperty(value, propName));
- }
- }
- }
- function emitArrayLiteralAssignment(target, value) {
- var elements = target.elements;
- if (elements.length !== 1) {
- // For anything but a single element destructuring we need to generate a temporary
- // to ensure value is evaluated exactly once.
- value = ensureIdentifier(value);
- }
- for (var i = 0; i < elements.length; i++) {
- var e = elements[i];
- if (e.kind !== 175 /* OmittedExpression */) {
- if (e.kind !== 173 /* SpreadElementExpression */) {
- emitDestructuringAssignment(e, createElementAccessExpression(value, createNumericLiteral(i)));
- }
- else if (i === elements.length - 1) {
- emitDestructuringAssignment(e.expression, createSliceCall(value, i));
- }
- }
- }
- }
- function emitDestructuringAssignment(target, value) {
- if (target.kind === 169 /* BinaryExpression */ && target.operatorToken.kind === 53 /* EqualsToken */) {
- value = createDefaultValueCheck(value, target.right);
- target = target.left;
- }
- if (target.kind === 154 /* ObjectLiteralExpression */) {
- emitObjectLiteralAssignment(target, value);
- }
- else if (target.kind === 153 /* ArrayLiteralExpression */) {
- emitArrayLiteralAssignment(target, value);
- }
- else {
- emitAssignment(target, value);
- }
- }
- function emitAssignmentExpression(root) {
- var target = root.left;
- var value = root.right;
- if (isAssignmentExpressionStatement) {
- emitDestructuringAssignment(target, value);
- }
- else {
- if (root.parent.kind !== 161 /* ParenthesizedExpression */) {
- write("(");
- }
- value = ensureIdentifier(value);
- emitDestructuringAssignment(target, value);
- write(", ");
- emit(value);
- if (root.parent.kind !== 161 /* ParenthesizedExpression */) {
- write(")");
- }
- }
- }
- function emitBindingElement(target, value) {
- if (target.initializer) {
- // Combine value and initializer
- value = value ? createDefaultValueCheck(value, target.initializer) : target.initializer;
- }
- else if (!value) {
- // Use 'void 0' in absence of value and initializer
- value = createVoidZero();
- }
- if (ts.isBindingPattern(target.name)) {
- var pattern = target.name;
- var elements = pattern.elements;
- if (elements.length !== 1) {
- // For anything but a single element destructuring we need to generate a temporary
- // to ensure value is evaluated exactly once.
- value = ensureIdentifier(value);
- }
- for (var i = 0; i < elements.length; i++) {
- var element = elements[i];
- if (pattern.kind === 150 /* ObjectBindingPattern */) {
- // Rewrite element to a declaration with an initializer that fetches property
- var propName = element.propertyName || element.name;
- emitBindingElement(element, createPropertyAccessForDestructuringProperty(value, propName));
- }
- else if (element.kind !== 175 /* OmittedExpression */) {
- if (!element.dotDotDotToken) {
- // Rewrite element to a declaration that accesses array element at index i
- emitBindingElement(element, createElementAccessExpression(value, createNumericLiteral(i)));
- }
- else if (i === elements.length - 1) {
- emitBindingElement(element, createSliceCall(value, i));
- }
- }
- }
- }
- else {
- emitAssignment(target.name, value);
- }
- }
- }
- function emitVariableDeclaration(node) {
- if (ts.isBindingPattern(node.name)) {
- if (languageVersion < 2 /* ES6 */) {
- emitDestructuring(node, false);
- }
- else {
- emit(node.name);
- emitOptional(" = ", node.initializer);
- }
- }
- else {
- renameNonTopLevelLetAndConst(node.name);
- var initializer = node.initializer;
- if (!initializer && languageVersion < 2 /* ES6 */) {
- // downlevel emit for non-initialized let bindings defined in loops
- // for (...) { let x; }
- // should be
- // for (...) { var = void 0; }
- // this is necessary to preserve ES6 semantic in scenarios like
- // for (...) { let x; console.log(x); x = 1 } // assignment on one iteration should not affect other iterations
- var isUninitializedLet = (resolver.getNodeCheckFlags(node) & 256 /* BlockScopedBindingInLoop */) &&
- (getCombinedFlagsForIdentifier(node.name) & 4096 /* Let */);
- // NOTE: default initialization should not be added to let bindings in for-in\for-of statements
- if (isUninitializedLet &&
- node.parent.parent.kind !== 187 /* ForInStatement */ &&
- node.parent.parent.kind !== 188 /* ForOfStatement */) {
- initializer = createVoidZero();
- }
- }
- var exportChanged = isNameOfExportedSourceLevelDeclarationInSystemExternalModule(node.name);
- if (exportChanged) {
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(node.name);
- write("\", ");
- }
- emitModuleMemberName(node);
- emitOptional(" = ", initializer);
- if (exportChanged) {
- write(")");
- }
- }
- }
- function emitExportVariableAssignments(node) {
- if (node.kind === 175 /* OmittedExpression */) {
- return;
- }
- var name = node.name;
- if (name.kind === 65 /* Identifier */) {
- emitExportMemberAssignments(name);
- }
- else if (ts.isBindingPattern(name)) {
- ts.forEach(name.elements, emitExportVariableAssignments);
- }
- }
- function getCombinedFlagsForIdentifier(node) {
- if (!node.parent || (node.parent.kind !== 198 /* VariableDeclaration */ && node.parent.kind !== 152 /* BindingElement */)) {
- return 0;
- }
- return ts.getCombinedNodeFlags(node.parent);
- }
- function renameNonTopLevelLetAndConst(node) {
- // do not rename if
- // - language version is ES6+
- // - node is synthesized
- // - node is not identifier (can happen when tree is malformed)
- // - node is definitely not name of variable declaration.
- // it still can be part of parameter declaration, this check will be done next
- if (languageVersion >= 2 /* ES6 */ ||
- ts.nodeIsSynthesized(node) ||
- node.kind !== 65 /* Identifier */ ||
- (node.parent.kind !== 198 /* VariableDeclaration */ && node.parent.kind !== 152 /* BindingElement */)) {
- return;
- }
- var combinedFlags = getCombinedFlagsForIdentifier(node);
- if (((combinedFlags & 12288 /* BlockScoped */) === 0) || combinedFlags & 1 /* Export */) {
- // do not rename exported or non-block scoped variables
- return;
- }
- // here it is known that node is a block scoped variable
- var list = ts.getAncestor(node, 199 /* VariableDeclarationList */);
- if (list.parent.kind === 180 /* VariableStatement */) {
- var isSourceFileLevelBinding = list.parent.parent.kind === 227 /* SourceFile */;
- var isModuleLevelBinding = list.parent.parent.kind === 206 /* ModuleBlock */;
- var isFunctionLevelBinding = list.parent.parent.kind === 179 /* Block */ && ts.isFunctionLike(list.parent.parent.parent);
- if (isSourceFileLevelBinding || isModuleLevelBinding || isFunctionLevelBinding) {
- return;
- }
- }
- var blockScopeContainer = ts.getEnclosingBlockScopeContainer(node);
- var parent = blockScopeContainer.kind === 227 /* SourceFile */
- ? blockScopeContainer
- : blockScopeContainer.parent;
- if (resolver.resolvesToSomeValue(parent, node.text)) {
- var variableId = resolver.getBlockScopedVariableId(node);
- if (!blockScopedVariableToGeneratedName) {
- blockScopedVariableToGeneratedName = [];
- }
- var generatedName = makeUniqueName(node.text);
- blockScopedVariableToGeneratedName[variableId] = generatedName;
- }
- }
- function isES6ExportedDeclaration(node) {
- return !!(node.flags & 1 /* Export */) &&
- languageVersion >= 2 /* ES6 */ &&
- node.parent.kind === 227 /* SourceFile */;
- }
- function emitVariableStatement(node) {
- var startIsEmitted = true;
- if (!(node.flags & 1 /* Export */)) {
- startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
- }
- else if (isES6ExportedDeclaration(node)) {
- // Exported ES6 module member
- write("export ");
- startIsEmitted = tryEmitStartOfVariableDeclarationList(node.declarationList);
- }
- if (startIsEmitted) {
- emitCommaList(node.declarationList.declarations);
- write(";");
- }
- else {
- var atLeastOneItem = emitVariableDeclarationListSkippingUninitializedEntries(node.declarationList);
- if (atLeastOneItem) {
- write(";");
- }
- }
- if (languageVersion < 2 /* ES6 */ && node.parent === currentSourceFile) {
- ts.forEach(node.declarationList.declarations, emitExportVariableAssignments);
- }
- }
- function emitParameter(node) {
- if (languageVersion < 2 /* ES6 */) {
- if (ts.isBindingPattern(node.name)) {
- var name_5 = createTempVariable(0 /* Auto */);
- if (!tempParameters) {
- tempParameters = [];
- }
- tempParameters.push(name_5);
- emit(name_5);
- }
- else {
- emit(node.name);
- }
- }
- else {
- if (node.dotDotDotToken) {
- write("...");
- }
- emit(node.name);
- emitOptional(" = ", node.initializer);
- }
- }
- function emitDefaultValueAssignments(node) {
- if (languageVersion < 2 /* ES6 */) {
- var tempIndex = 0;
- ts.forEach(node.parameters, function (p) {
- // A rest parameter cannot have a binding pattern or an initializer,
- // so let's just ignore it.
- if (p.dotDotDotToken) {
- return;
- }
- if (ts.isBindingPattern(p.name)) {
- writeLine();
- write("var ");
- emitDestructuring(p, false, tempParameters[tempIndex]);
- write(";");
- tempIndex++;
- }
- else if (p.initializer) {
- writeLine();
- emitStart(p);
- write("if (");
- emitNodeWithoutSourceMap(p.name);
- write(" === void 0)");
- emitEnd(p);
- write(" { ");
- emitStart(p);
- emitNodeWithoutSourceMap(p.name);
- write(" = ");
- emitNodeWithoutSourceMap(p.initializer);
- emitEnd(p);
- write("; }");
- }
- });
- }
- }
- function emitRestParameter(node) {
- if (languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node)) {
- var restIndex = node.parameters.length - 1;
- var restParam = node.parameters[restIndex];
- // A rest parameter cannot have a binding pattern, so let's just ignore it if it does.
- if (ts.isBindingPattern(restParam.name)) {
- return;
- }
- var tempName = createTempVariable(268435456 /* _i */).text;
- writeLine();
- emitLeadingComments(restParam);
- emitStart(restParam);
- write("var ");
- emitNodeWithoutSourceMap(restParam.name);
- write(" = [];");
- emitEnd(restParam);
- emitTrailingComments(restParam);
- writeLine();
- write("for (");
- emitStart(restParam);
- write("var " + tempName + " = " + restIndex + ";");
- emitEnd(restParam);
- write(" ");
- emitStart(restParam);
- write(tempName + " < arguments.length;");
- emitEnd(restParam);
- write(" ");
- emitStart(restParam);
- write(tempName + "++");
- emitEnd(restParam);
- write(") {");
- increaseIndent();
- writeLine();
- emitStart(restParam);
- emitNodeWithoutSourceMap(restParam.name);
- write("[" + tempName + " - " + restIndex + "] = arguments[" + tempName + "];");
- emitEnd(restParam);
- decreaseIndent();
- writeLine();
- write("}");
- }
- }
- function emitAccessor(node) {
- write(node.kind === 136 /* GetAccessor */ ? "get " : "set ");
- emit(node.name, false);
- emitSignatureAndBody(node);
- }
- function shouldEmitAsArrowFunction(node) {
- return node.kind === 163 /* ArrowFunction */ && languageVersion >= 2 /* ES6 */;
- }
- function emitDeclarationName(node) {
- if (node.name) {
- emitNodeWithoutSourceMap(node.name);
- }
- else {
- write(getGeneratedNameForNode(node));
- }
- }
- function shouldEmitFunctionName(node) {
- if (node.kind === 162 /* FunctionExpression */) {
- // Emit name if one is present
- return !!node.name;
- }
- if (node.kind === 200 /* FunctionDeclaration */) {
- // Emit name if one is present, or emit generated name in down-level case (for export default case)
- return !!node.name || languageVersion < 2 /* ES6 */;
- }
- }
- function emitFunctionDeclaration(node) {
- if (ts.nodeIsMissing(node.body)) {
- return emitOnlyPinnedOrTripleSlashComments(node);
- }
- if (node.kind !== 134 /* MethodDeclaration */ && node.kind !== 133 /* MethodSignature */) {
- // Methods will emit the comments as part of emitting method declaration
- emitLeadingComments(node);
- }
- // For targeting below es6, emit functions-like declaration including arrow function using function keyword.
- // When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead
- if (!shouldEmitAsArrowFunction(node)) {
- if (isES6ExportedDeclaration(node)) {
- write("export ");
- if (node.flags & 256 /* Default */) {
- write("default ");
- }
- }
- write("function");
- if (languageVersion >= 2 /* ES6 */ && node.asteriskToken) {
- write("*");
- }
- write(" ");
- }
- if (shouldEmitFunctionName(node)) {
- emitDeclarationName(node);
- }
- emitSignatureAndBody(node);
- if (languageVersion < 2 /* ES6 */ && node.kind === 200 /* FunctionDeclaration */ && node.parent === currentSourceFile && node.name) {
- emitExportMemberAssignments(node.name);
- }
- if (node.kind !== 134 /* MethodDeclaration */ && node.kind !== 133 /* MethodSignature */) {
- emitTrailingComments(node);
- }
- }
- function emitCaptureThisForNodeIfNecessary(node) {
- if (resolver.getNodeCheckFlags(node) & 4 /* CaptureThis */) {
- writeLine();
- emitStart(node);
- write("var _this = this;");
- emitEnd(node);
- }
- }
- function emitSignatureParameters(node) {
- increaseIndent();
- write("(");
- if (node) {
- var parameters = node.parameters;
- var omitCount = languageVersion < 2 /* ES6 */ && ts.hasRestParameters(node) ? 1 : 0;
- emitList(parameters, 0, parameters.length - omitCount, false, false);
- }
- write(")");
- decreaseIndent();
- }
- function emitSignatureParametersForArrow(node) {
- // Check whether the parameter list needs parentheses and preserve no-parenthesis
- if (node.parameters.length === 1 && node.pos === node.parameters[0].pos) {
- emit(node.parameters[0]);
- return;
- }
- emitSignatureParameters(node);
- }
- function emitSignatureAndBody(node) {
- var saveTempFlags = tempFlags;
- var saveTempVariables = tempVariables;
- var saveTempParameters = tempParameters;
- tempFlags = 0;
- tempVariables = undefined;
- tempParameters = undefined;
- // When targeting ES6, emit arrow function natively in ES6
- if (shouldEmitAsArrowFunction(node)) {
- emitSignatureParametersForArrow(node);
- write(" =>");
- }
- else {
- emitSignatureParameters(node);
- }
- if (!node.body) {
- // There can be no body when there are parse errors. Just emit an empty block
- // in that case.
- write(" { }");
- }
- else if (node.body.kind === 179 /* Block */) {
- emitBlockFunctionBody(node, node.body);
- }
- else {
- emitExpressionFunctionBody(node, node.body);
- }
- if (!isES6ExportedDeclaration(node)) {
- emitExportMemberAssignment(node);
- }
- tempFlags = saveTempFlags;
- tempVariables = saveTempVariables;
- tempParameters = saveTempParameters;
- }
- // Returns true if any preamble code was emitted.
- function emitFunctionBodyPreamble(node) {
- emitCaptureThisForNodeIfNecessary(node);
- emitDefaultValueAssignments(node);
- emitRestParameter(node);
- }
- function emitExpressionFunctionBody(node, body) {
- if (languageVersion < 2 /* ES6 */) {
- emitDownLevelExpressionFunctionBody(node, body);
- return;
- }
- // For es6 and higher we can emit the expression as is. However, in the case
- // where the expression might end up looking like a block when emitted, we'll
- // also wrap it in parentheses first. For example if you have: a => {}
- // then we need to generate: a => ({})
- write(" ");
- // Unwrap all type assertions.
- var current = body;
- while (current.kind === 160 /* TypeAssertionExpression */) {
- current = current.expression;
- }
- emitParenthesizedIf(body, current.kind === 154 /* ObjectLiteralExpression */);
- }
- function emitDownLevelExpressionFunctionBody(node, body) {
- write(" {");
- scopeEmitStart(node);
- increaseIndent();
- var outPos = writer.getTextPos();
- emitDetachedComments(node.body);
- emitFunctionBodyPreamble(node);
- var preambleEmitted = writer.getTextPos() !== outPos;
- decreaseIndent();
- // If we didn't have to emit any preamble code, then attempt to keep the arrow
- // function on one line.
- if (!preambleEmitted && nodeStartPositionsAreOnSameLine(node, body)) {
- write(" ");
- emitStart(body);
- write("return ");
- emit(body);
- emitEnd(body);
- write(";");
- emitTempDeclarations(false);
- write(" ");
- }
- else {
- increaseIndent();
- writeLine();
- emitLeadingComments(node.body);
- write("return ");
- emit(body);
- write(";");
- emitTrailingComments(node.body);
- emitTempDeclarations(true);
- decreaseIndent();
- writeLine();
- }
- emitStart(node.body);
- write("}");
- emitEnd(node.body);
- scopeEmitEnd();
- }
- function emitBlockFunctionBody(node, body) {
- write(" {");
- scopeEmitStart(node);
- var initialTextPos = writer.getTextPos();
- increaseIndent();
- emitDetachedComments(body.statements);
- // Emit all the directive prologues (like "use strict"). These have to come before
- // any other preamble code we write (like parameter initializers).
- var startIndex = emitDirectivePrologues(body.statements, true);
- emitFunctionBodyPreamble(node);
- decreaseIndent();
- var preambleEmitted = writer.getTextPos() !== initialTextPos;
- if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)) {
- for (var _i = 0, _a = body.statements; _i < _a.length; _i++) {
- var statement = _a[_i];
- write(" ");
- emit(statement);
- }
- emitTempDeclarations(false);
- write(" ");
- emitLeadingCommentsOfPosition(body.statements.end);
- }
- else {
- increaseIndent();
- emitLinesStartingAt(body.statements, startIndex);
- emitTempDeclarations(true);
- writeLine();
- emitLeadingCommentsOfPosition(body.statements.end);
- decreaseIndent();
- }
- emitToken(15 /* CloseBraceToken */, body.statements.end);
- scopeEmitEnd();
- }
- function findInitialSuperCall(ctor) {
- if (ctor.body) {
- var statement = ctor.body.statements[0];
- if (statement && statement.kind === 182 /* ExpressionStatement */) {
- var expr = statement.expression;
- if (expr && expr.kind === 157 /* CallExpression */) {
- var func = expr.expression;
- if (func && func.kind === 91 /* SuperKeyword */) {
- return statement;
- }
- }
- }
- }
- }
- function emitParameterPropertyAssignments(node) {
- ts.forEach(node.parameters, function (param) {
- if (param.flags & 112 /* AccessibilityModifier */) {
- writeLine();
- emitStart(param);
- emitStart(param.name);
- write("this.");
- emitNodeWithoutSourceMap(param.name);
- emitEnd(param.name);
- write(" = ");
- emit(param.name);
- write(";");
- emitEnd(param);
- }
- });
- }
- function emitMemberAccessForPropertyName(memberName) {
- // TODO: (jfreeman,drosen): comment on why this is emitNodeWithoutSourceMap instead of emit here.
- if (memberName.kind === 8 /* StringLiteral */ || memberName.kind === 7 /* NumericLiteral */) {
- write("[");
- emitNodeWithoutSourceMap(memberName);
- write("]");
- }
- else if (memberName.kind === 127 /* ComputedPropertyName */) {
- emitComputedPropertyName(memberName);
- }
- else {
- write(".");
- emitNodeWithoutSourceMap(memberName);
- }
- }
- function getInitializedProperties(node, static) {
- var properties = [];
- for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
- var member = _a[_i];
- if (member.kind === 132 /* PropertyDeclaration */ && static === ((member.flags & 128 /* Static */) !== 0) && member.initializer) {
- properties.push(member);
- }
- }
- return properties;
- }
- function emitPropertyDeclarations(node, properties) {
- for (var _i = 0; _i < properties.length; _i++) {
- var property = properties[_i];
- emitPropertyDeclaration(node, property);
- }
- }
- function emitPropertyDeclaration(node, property, receiver, isExpression) {
- writeLine();
- emitLeadingComments(property);
- emitStart(property);
- emitStart(property.name);
- if (receiver) {
- emit(receiver);
- }
- else {
- if (property.flags & 128 /* Static */) {
- emitDeclarationName(node);
- }
- else {
- write("this");
- }
- }
- emitMemberAccessForPropertyName(property.name);
- emitEnd(property.name);
- write(" = ");
- emit(property.initializer);
- if (!isExpression) {
- write(";");
- }
- emitEnd(property);
- emitTrailingComments(property);
- }
- function emitMemberFunctionsForES5AndLower(node) {
- ts.forEach(node.members, function (member) {
- if (member.kind === 178 /* SemicolonClassElement */) {
- writeLine();
- write(";");
- }
- else if (member.kind === 134 /* MethodDeclaration */ || node.kind === 133 /* MethodSignature */) {
- if (!member.body) {
- return emitOnlyPinnedOrTripleSlashComments(member);
- }
- writeLine();
- emitLeadingComments(member);
- emitStart(member);
- emitStart(member.name);
- emitClassMemberPrefix(node, member);
- emitMemberAccessForPropertyName(member.name);
- emitEnd(member.name);
- write(" = ");
- emitStart(member);
- emitFunctionDeclaration(member);
- emitEnd(member);
- emitEnd(member);
- write(";");
- emitTrailingComments(member);
- }
- else if (member.kind === 136 /* GetAccessor */ || member.kind === 137 /* SetAccessor */) {
- var accessors = ts.getAllAccessorDeclarations(node.members, member);
- if (member === accessors.firstAccessor) {
- writeLine();
- emitStart(member);
- write("Object.defineProperty(");
- emitStart(member.name);
- emitClassMemberPrefix(node, member);
- write(", ");
- emitExpressionForPropertyName(member.name);
- emitEnd(member.name);
- write(", {");
- increaseIndent();
- if (accessors.getAccessor) {
- writeLine();
- emitLeadingComments(accessors.getAccessor);
- write("get: ");
- emitStart(accessors.getAccessor);
- write("function ");
- emitSignatureAndBody(accessors.getAccessor);
- emitEnd(accessors.getAccessor);
- emitTrailingComments(accessors.getAccessor);
- write(",");
- }
- if (accessors.setAccessor) {
- writeLine();
- emitLeadingComments(accessors.setAccessor);
- write("set: ");
- emitStart(accessors.setAccessor);
- write("function ");
- emitSignatureAndBody(accessors.setAccessor);
- emitEnd(accessors.setAccessor);
- emitTrailingComments(accessors.setAccessor);
- write(",");
- }
- writeLine();
- write("enumerable: true,");
- writeLine();
- write("configurable: true");
- decreaseIndent();
- writeLine();
- write("});");
- emitEnd(member);
- }
- }
- });
- }
- function emitMemberFunctionsForES6AndHigher(node) {
- for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
- var member = _a[_i];
- if ((member.kind === 134 /* MethodDeclaration */ || node.kind === 133 /* MethodSignature */) && !member.body) {
- emitOnlyPinnedOrTripleSlashComments(member);
- }
- else if (member.kind === 134 /* MethodDeclaration */ ||
- member.kind === 136 /* GetAccessor */ ||
- member.kind === 137 /* SetAccessor */) {
- writeLine();
- emitLeadingComments(member);
- emitStart(member);
- if (member.flags & 128 /* Static */) {
- write("static ");
- }
- if (member.kind === 136 /* GetAccessor */) {
- write("get ");
- }
- else if (member.kind === 137 /* SetAccessor */) {
- write("set ");
- }
- if (member.asteriskToken) {
- write("*");
- }
- emit(member.name);
- emitSignatureAndBody(member);
- emitEnd(member);
- emitTrailingComments(member);
- }
- else if (member.kind === 178 /* SemicolonClassElement */) {
- writeLine();
- write(";");
- }
- }
- }
- function emitConstructor(node, baseTypeElement) {
- var saveTempFlags = tempFlags;
- var saveTempVariables = tempVariables;
- var saveTempParameters = tempParameters;
- tempFlags = 0;
- tempVariables = undefined;
- tempParameters = undefined;
- emitConstructorWorker(node, baseTypeElement);
- tempFlags = saveTempFlags;
- tempVariables = saveTempVariables;
- tempParameters = saveTempParameters;
- }
- function emitConstructorWorker(node, baseTypeElement) {
- // Check if we have property assignment inside class declaration.
- // If there is property assignment, we need to emit constructor whether users define it or not
- // If there is no property assignment, we can omit constructor if users do not define it
- var hasInstancePropertyWithInitializer = false;
- // Emit the constructor overload pinned comments
- ts.forEach(node.members, function (member) {
- if (member.kind === 135 /* Constructor */ && !member.body) {
- emitOnlyPinnedOrTripleSlashComments(member);
- }
- // Check if there is any non-static property assignment
- if (member.kind === 132 /* PropertyDeclaration */ && member.initializer && (member.flags & 128 /* Static */) === 0) {
- hasInstancePropertyWithInitializer = true;
- }
- });
- var ctor = ts.getFirstConstructorWithBody(node);
- // For target ES6 and above, if there is no user-defined constructor and there is no property assignment
- // do not emit constructor in class declaration.
- if (languageVersion >= 2 /* ES6 */ && !ctor && !hasInstancePropertyWithInitializer) {
- return;
- }
- if (ctor) {
- emitLeadingComments(ctor);
- }
- emitStart(ctor || node);
- if (languageVersion < 2 /* ES6 */) {
- write("function ");
- emitDeclarationName(node);
- emitSignatureParameters(ctor);
- }
- else {
- write("constructor");
- if (ctor) {
- emitSignatureParameters(ctor);
- }
- else {
- // Based on EcmaScript6 section 14.5.14: Runtime Semantics: ClassDefinitionEvaluation.
- // If constructor is empty, then,
- // If ClassHeritageopt is present, then
- // Let constructor be the result of parsing the String "constructor(... args){ super (...args);}" using the syntactic grammar with the goal symbol MethodDefinition.
- // Else,
- // Let constructor be the result of parsing the String "constructor( ){ }" using the syntactic grammar with the goal symbol MethodDefinition
- if (baseTypeElement) {
- write("(...args)");
- }
- else {
- write("()");
- }
- }
- }
- write(" {");
- scopeEmitStart(node, "constructor");
- increaseIndent();
- if (ctor) {
- emitDetachedComments(ctor.body.statements);
- }
- emitCaptureThisForNodeIfNecessary(node);
- if (ctor) {
- emitDefaultValueAssignments(ctor);
- emitRestParameter(ctor);
- if (baseTypeElement) {
- var superCall = findInitialSuperCall(ctor);
- if (superCall) {
- writeLine();
- emit(superCall);
- }
- }
- emitParameterPropertyAssignments(ctor);
- }
- else {
- if (baseTypeElement) {
- writeLine();
- emitStart(baseTypeElement);
- if (languageVersion < 2 /* ES6 */) {
- write("_super.apply(this, arguments);");
- }
- else {
- write("super(...args);");
- }
- emitEnd(baseTypeElement);
- }
- }
- emitPropertyDeclarations(node, getInitializedProperties(node, false));
- if (ctor) {
- var statements = ctor.body.statements;
- if (superCall) {
- statements = statements.slice(1);
- }
- emitLines(statements);
- }
- emitTempDeclarations(true);
- writeLine();
- if (ctor) {
- emitLeadingCommentsOfPosition(ctor.body.statements.end);
- }
- decreaseIndent();
- emitToken(15 /* CloseBraceToken */, ctor ? ctor.body.statements.end : node.members.end);
- scopeEmitEnd();
- emitEnd(ctor || node);
- if (ctor) {
- emitTrailingComments(ctor);
- }
- }
- function emitClassExpression(node) {
- return emitClassLikeDeclaration(node);
- }
- function emitClassDeclaration(node) {
- return emitClassLikeDeclaration(node);
- }
- function emitClassLikeDeclaration(node) {
- if (languageVersion < 2 /* ES6 */) {
- emitClassLikeDeclarationBelowES6(node);
- }
- else {
- emitClassLikeDeclarationForES6AndHigher(node);
- }
- }
- function emitClassLikeDeclarationForES6AndHigher(node) {
- var thisNodeIsDecorated = ts.nodeIsDecorated(node);
- if (node.kind === 201 /* ClassDeclaration */) {
- if (thisNodeIsDecorated) {
- // To preserve the correct runtime semantics when decorators are applied to the class,
- // the emit needs to follow one of the following rules:
- //
- // * For a local class declaration:
- //
- // @dec class C {
- // }
- //
- // The emit should be:
- //
- // let C = class {
- // };
- // Object.defineProperty(C, "name", { value: "C", configurable: true });
- // C = __decorate([dec], C);
- //
- // * For an exported class declaration:
- //
- // @dec export class C {
- // }
- //
- // The emit should be:
- //
- // export let C = class {
- // };
- // Object.defineProperty(C, "name", { value: "C", configurable: true });
- // C = __decorate([dec], C);
- //
- // * For a default export of a class declaration with a name:
- //
- // @dec default export class C {
- // }
- //
- // The emit should be:
- //
- // let C = class {
- // }
- // Object.defineProperty(C, "name", { value: "C", configurable: true });
- // C = __decorate([dec], C);
- // export default C;
- //
- // * For a default export of a class declaration without a name:
- //
- // @dec default export class {
- // }
- //
- // The emit should be:
- //
- // let _default = class {
- // }
- // _default = __decorate([dec], _default);
- // export default _default;
- //
- if (isES6ExportedDeclaration(node) && !(node.flags & 256 /* Default */)) {
- write("export ");
- }
- write("let ");
- emitDeclarationName(node);
- write(" = ");
- }
- else if (isES6ExportedDeclaration(node)) {
- write("export ");
- if (node.flags & 256 /* Default */) {
- write("default ");
- }
- }
- }
- // If the class has static properties, and it's a class expression, then we'll need
- // to specialize the emit a bit. for a class expression of the form:
- //
- // class C { static a = 1; static b = 2; ... }
- //
- // We'll emit:
- //
- // (_temp = class C { ... }, _temp.a = 1, _temp.b = 2, _temp)
- //
- // This keeps the expression as an expression, while ensuring that the static parts
- // of it have been initialized by the time it is used.
- var staticProperties = getInitializedProperties(node, true);
- var isClassExpressionWithStaticProperties = staticProperties.length > 0 && node.kind === 174 /* ClassExpression */;
- var tempVariable;
- if (isClassExpressionWithStaticProperties) {
- tempVariable = createAndRecordTempVariable(0 /* Auto */);
- write("(");
- increaseIndent();
- emit(tempVariable);
- write(" = ");
- }
- write("class");
- // check if this is an "export default class" as it may not have a name. Do not emit the name if the class is decorated.
- if ((node.name || !(node.flags & 256 /* Default */)) && !thisNodeIsDecorated) {
- write(" ");
- emitDeclarationName(node);
- }
- var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
- if (baseTypeNode) {
- write(" extends ");
- emit(baseTypeNode.expression);
- }
- write(" {");
- increaseIndent();
- scopeEmitStart(node);
- writeLine();
- emitConstructor(node, baseTypeNode);
- emitMemberFunctionsForES6AndHigher(node);
- decreaseIndent();
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.members.end);
- scopeEmitEnd();
- // For a decorated class, we need to assign its name (if it has one). This is because we emit
- // the class as a class expression to avoid the double-binding of the identifier:
- //
- // let C = class {
- // }
- // Object.defineProperty(C, "name", { value: "C", configurable: true });
- //
- if (thisNodeIsDecorated) {
- write(";");
- if (node.name) {
- writeLine();
- write("Object.defineProperty(");
- emitDeclarationName(node);
- write(", \"name\", { value: \"");
- emitDeclarationName(node);
- write("\", configurable: true });");
- writeLine();
- }
- }
- // Emit static property assignment. Because classDeclaration is lexically evaluated,
- // it is safe to emit static property assignment after classDeclaration
- // From ES6 specification:
- // HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using
- // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration.
- if (isClassExpressionWithStaticProperties) {
- for (var _i = 0; _i < staticProperties.length; _i++) {
- var property = staticProperties[_i];
- write(",");
- writeLine();
- emitPropertyDeclaration(node, property, tempVariable, true);
- }
- write(",");
- writeLine();
- emit(tempVariable);
- decreaseIndent();
- write(")");
- }
- else {
- writeLine();
- emitPropertyDeclarations(node, staticProperties);
- emitDecoratorsOfClass(node);
- }
- // If this is an exported class, but not on the top level (i.e. on an internal
- // module), export it
- if (!isES6ExportedDeclaration(node) && (node.flags & 1 /* Export */)) {
- writeLine();
- emitStart(node);
- emitModuleMemberName(node);
- write(" = ");
- emitDeclarationName(node);
- emitEnd(node);
- write(";");
- }
- else if (isES6ExportedDeclaration(node) && (node.flags & 256 /* Default */) && thisNodeIsDecorated) {
- // if this is a top level default export of decorated class, write the export after the declaration.
- writeLine();
- write("export default ");
- emitDeclarationName(node);
- write(";");
- }
- }
- function emitClassLikeDeclarationBelowES6(node) {
- if (node.kind === 201 /* ClassDeclaration */) {
- // source file level classes in system modules are hoisted so 'var's for them are already defined
- if (!isSourceFileLevelDeclarationInSystemExternalModule(node, false)) {
- write("var ");
- }
- emitDeclarationName(node);
- write(" = ");
- }
- write("(function (");
- var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node);
- if (baseTypeNode) {
- write("_super");
- }
- write(") {");
- var saveTempFlags = tempFlags;
- var saveTempVariables = tempVariables;
- var saveTempParameters = tempParameters;
- var saveComputedPropertyNamesToGeneratedNames = computedPropertyNamesToGeneratedNames;
- tempFlags = 0;
- tempVariables = undefined;
- tempParameters = undefined;
- computedPropertyNamesToGeneratedNames = undefined;
- increaseIndent();
- scopeEmitStart(node);
- if (baseTypeNode) {
- writeLine();
- emitStart(baseTypeNode);
- write("__extends(");
- emitDeclarationName(node);
- write(", _super);");
- emitEnd(baseTypeNode);
- }
- writeLine();
- emitConstructor(node, baseTypeNode);
- emitMemberFunctionsForES5AndLower(node);
- emitPropertyDeclarations(node, getInitializedProperties(node, true));
- writeLine();
- emitDecoratorsOfClass(node);
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.members.end, function () {
- write("return ");
- emitDeclarationName(node);
- });
- write(";");
- emitTempDeclarations(true);
- tempFlags = saveTempFlags;
- tempVariables = saveTempVariables;
- tempParameters = saveTempParameters;
- computedPropertyNamesToGeneratedNames = saveComputedPropertyNamesToGeneratedNames;
- decreaseIndent();
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.members.end);
- scopeEmitEnd();
- emitStart(node);
- write(")(");
- if (baseTypeNode) {
- emit(baseTypeNode.expression);
- }
- write(")");
- if (node.kind === 201 /* ClassDeclaration */) {
- write(";");
- }
- emitEnd(node);
- if (node.kind === 201 /* ClassDeclaration */) {
- emitExportMemberAssignment(node);
- }
- if (languageVersion < 2 /* ES6 */ && node.parent === currentSourceFile && node.name) {
- emitExportMemberAssignments(node.name);
- }
- }
- function emitClassMemberPrefix(node, member) {
- emitDeclarationName(node);
- if (!(member.flags & 128 /* Static */)) {
- write(".prototype");
- }
- }
- function emitDecoratorsOfClass(node) {
- emitDecoratorsOfMembers(node, 0);
- emitDecoratorsOfMembers(node, 128 /* Static */);
- emitDecoratorsOfConstructor(node);
- }
- function emitDecoratorsOfConstructor(node) {
- var decorators = node.decorators;
- var constructor = ts.getFirstConstructorWithBody(node);
- var hasDecoratedParameters = constructor && ts.forEach(constructor.parameters, ts.nodeIsDecorated);
- // skip decoration of the constructor if neither it nor its parameters are decorated
- if (!decorators && !hasDecoratedParameters) {
- return;
- }
- // Emit the call to __decorate. Given the class:
- //
- // @dec
- // class C {
- // }
- //
- // The emit for the class is:
- //
- // C = __decorate([dec], C);
- //
- writeLine();
- emitStart(node);
- emitDeclarationName(node);
- write(" = __decorate([");
- increaseIndent();
- writeLine();
- var decoratorCount = decorators ? decorators.length : 0;
- var argumentsWritten = emitList(decorators, 0, decoratorCount, true, false, false, true, function (decorator) {
- emitStart(decorator);
- emit(decorator.expression);
- emitEnd(decorator);
- });
- argumentsWritten += emitDecoratorsOfParameters(constructor, argumentsWritten > 0);
- emitSerializedTypeMetadata(node, argumentsWritten >= 0);
- decreaseIndent();
- writeLine();
- write("], ");
- emitDeclarationName(node);
- write(");");
- emitEnd(node);
- writeLine();
- }
- function emitDecoratorsOfMembers(node, staticFlag) {
- for (var _i = 0, _a = node.members; _i < _a.length; _i++) {
- var member = _a[_i];
- // only emit members in the correct group
- if ((member.flags & 128 /* Static */) !== staticFlag) {
- continue;
- }
- // skip members that cannot be decorated (such as the constructor)
- if (!ts.nodeCanBeDecorated(member)) {
- continue;
- }
- // skip a member if it or any of its parameters are not decorated
- if (!ts.nodeOrChildIsDecorated(member)) {
- continue;
- }
- // skip an accessor declaration if it is not the first accessor
- var decorators = void 0;
- var functionLikeMember = void 0;
- if (ts.isAccessor(member)) {
- var accessors = ts.getAllAccessorDeclarations(node.members, member);
- if (member !== accessors.firstAccessor) {
- continue;
- }
- // get the decorators from the first accessor with decorators
- decorators = accessors.firstAccessor.decorators;
- if (!decorators && accessors.secondAccessor) {
- decorators = accessors.secondAccessor.decorators;
- }
- // we only decorate parameters of the set accessor
- functionLikeMember = accessors.setAccessor;
- }
- else {
- decorators = member.decorators;
- // we only decorate the parameters here if this is a method
- if (member.kind === 134 /* MethodDeclaration */) {
- functionLikeMember = member;
- }
- }
- // Emit the call to __decorate. Given the following:
- //
- // class C {
- // @dec method(@dec2 x) {}
- // @dec get accessor() {}
- // @dec prop;
- // }
- //
- // The emit for a method is:
- //
- // Object.defineProperty(C.prototype, "method",
- // __decorate([
- // dec,
- // __param(0, dec2),
- // __metadata("design:type", Function),
- // __metadata("design:paramtypes", [Object]),
- // __metadata("design:returntype", void 0)
- // ], C.prototype, "method", Object.getOwnPropertyDescriptor(C.prototype, "method")));
- //
- // The emit for an accessor is:
- //
- // Object.defineProperty(C.prototype, "accessor",
- // __decorate([
- // dec
- // ], C.prototype, "accessor", Object.getOwnPropertyDescriptor(C.prototype, "accessor")));
- //
- // The emit for a property is:
- //
- // __decorate([
- // dec
- // ], C.prototype, "prop");
- //
- writeLine();
- emitStart(member);
- if (member.kind !== 132 /* PropertyDeclaration */) {
- write("Object.defineProperty(");
- emitStart(member.name);
- emitClassMemberPrefix(node, member);
- write(", ");
- emitExpressionForPropertyName(member.name);
- emitEnd(member.name);
- write(",");
- increaseIndent();
- writeLine();
- }
- write("__decorate([");
- increaseIndent();
- writeLine();
- var decoratorCount = decorators ? decorators.length : 0;
- var argumentsWritten = emitList(decorators, 0, decoratorCount, true, false, false, true, function (decorator) {
- emitStart(decorator);
- emit(decorator.expression);
- emitEnd(decorator);
- });
- argumentsWritten += emitDecoratorsOfParameters(functionLikeMember, argumentsWritten > 0);
- emitSerializedTypeMetadata(member, argumentsWritten > 0);
- decreaseIndent();
- writeLine();
- write("], ");
- emitStart(member.name);
- emitClassMemberPrefix(node, member);
- write(", ");
- emitExpressionForPropertyName(member.name);
- emitEnd(member.name);
- if (member.kind !== 132 /* PropertyDeclaration */) {
- write(", Object.getOwnPropertyDescriptor(");
- emitStart(member.name);
- emitClassMemberPrefix(node, member);
- write(", ");
- emitExpressionForPropertyName(member.name);
- emitEnd(member.name);
- write("))");
- decreaseIndent();
- }
- write(");");
- emitEnd(member);
- writeLine();
- }
- }
- function emitDecoratorsOfParameters(node, leadingComma) {
- var argumentsWritten = 0;
- if (node) {
- var parameterIndex = 0;
- for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) {
- var parameter = _a[_i];
- if (ts.nodeIsDecorated(parameter)) {
- var decorators = parameter.decorators;
- argumentsWritten += emitList(decorators, 0, decorators.length, true, false, leadingComma, true, function (decorator) {
- emitStart(decorator);
- write("__param(" + parameterIndex + ", ");
- emit(decorator.expression);
- write(")");
- emitEnd(decorator);
- });
- leadingComma = true;
- }
- ++parameterIndex;
- }
- }
- return argumentsWritten;
- }
- function shouldEmitTypeMetadata(node) {
- // This method determines whether to emit the "design:type" metadata based on the node's kind.
- // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
- // compiler option is set.
- switch (node.kind) {
- case 134 /* MethodDeclaration */:
- case 136 /* GetAccessor */:
- case 137 /* SetAccessor */:
- case 132 /* PropertyDeclaration */:
- return true;
- }
- return false;
- }
- function shouldEmitReturnTypeMetadata(node) {
- // This method determines whether to emit the "design:returntype" metadata based on the node's kind.
- // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
- // compiler option is set.
- switch (node.kind) {
- case 134 /* MethodDeclaration */:
- return true;
- }
- return false;
- }
- function shouldEmitParamTypesMetadata(node) {
- // This method determines whether to emit the "design:paramtypes" metadata based on the node's kind.
- // The caller should have already tested whether the node has decorators and whether the emitDecoratorMetadata
- // compiler option is set.
- switch (node.kind) {
- case 201 /* ClassDeclaration */:
- case 134 /* MethodDeclaration */:
- case 137 /* SetAccessor */:
- return true;
- }
- return false;
- }
- function emitSerializedTypeMetadata(node, writeComma) {
- // This method emits the serialized type metadata for a decorator target.
- // The caller should have already tested whether the node has decorators.
- var argumentsWritten = 0;
- if (compilerOptions.emitDecoratorMetadata) {
- if (shouldEmitTypeMetadata(node)) {
- var serializedType = resolver.serializeTypeOfNode(node, getGeneratedNameForNode);
- if (serializedType) {
- if (writeComma) {
- write(", ");
- }
- writeLine();
- write("__metadata('design:type', ");
- emitSerializedType(node, serializedType);
- write(")");
- argumentsWritten++;
- }
- }
- if (shouldEmitParamTypesMetadata(node)) {
- var serializedTypes = resolver.serializeParameterTypesOfNode(node, getGeneratedNameForNode);
- if (serializedTypes) {
- if (writeComma || argumentsWritten) {
- write(", ");
- }
- writeLine();
- write("__metadata('design:paramtypes', [");
- for (var i = 0; i < serializedTypes.length; ++i) {
- if (i > 0) {
- write(", ");
- }
- emitSerializedType(node, serializedTypes[i]);
- }
- write("])");
- argumentsWritten++;
- }
- }
- if (shouldEmitReturnTypeMetadata(node)) {
- var serializedType = resolver.serializeReturnTypeOfNode(node, getGeneratedNameForNode);
- if (serializedType) {
- if (writeComma || argumentsWritten) {
- write(", ");
- }
- writeLine();
- write("__metadata('design:returntype', ");
- emitSerializedType(node, serializedType);
- write(")");
- argumentsWritten++;
- }
- }
- }
- return argumentsWritten;
- }
- function serializeTypeNameSegment(location, path, index) {
- switch (index) {
- case 0:
- return "typeof " + path[index] + " !== 'undefined' && " + path[index];
- case 1:
- return serializeTypeNameSegment(location, path, index - 1) + "." + path[index];
- default:
- var temp = createAndRecordTempVariable(0 /* Auto */).text;
- return "(" + temp + " = " + serializeTypeNameSegment(location, path, index - 1) + ") && " + temp + "." + path[index];
- }
- }
- function emitSerializedType(location, name) {
- if (typeof name === "string") {
- write(name);
- return;
- }
- else {
- ts.Debug.assert(name.length > 0, "Invalid serialized type name");
- write("(" + serializeTypeNameSegment(location, name, name.length - 1) + ") || Object");
- }
- }
- function emitInterfaceDeclaration(node) {
- emitOnlyPinnedOrTripleSlashComments(node);
- }
- function shouldEmitEnumDeclaration(node) {
- var isConstEnum = ts.isConst(node);
- return !isConstEnum || compilerOptions.preserveConstEnums || compilerOptions.separateCompilation;
- }
- function emitEnumDeclaration(node) {
- // const enums are completely erased during compilation.
- if (!shouldEmitEnumDeclaration(node)) {
- return;
- }
- if (!(node.flags & 1 /* Export */) || isES6ExportedDeclaration(node)) {
- emitStart(node);
- if (isES6ExportedDeclaration(node)) {
- write("export ");
- }
- write("var ");
- emit(node.name);
- emitEnd(node);
- write(";");
- }
- writeLine();
- emitStart(node);
- write("(function (");
- emitStart(node.name);
- write(getGeneratedNameForNode(node));
- emitEnd(node.name);
- write(") {");
- increaseIndent();
- scopeEmitStart(node);
- emitLines(node.members);
- decreaseIndent();
- writeLine();
- emitToken(15 /* CloseBraceToken */, node.members.end);
- scopeEmitEnd();
- write(")(");
- emitModuleMemberName(node);
- write(" || (");
- emitModuleMemberName(node);
- write(" = {}));");
- emitEnd(node);
- if (!isES6ExportedDeclaration(node) && node.flags & 1 /* Export */) {
- writeLine();
- emitStart(node);
- write("var ");
- emit(node.name);
- write(" = ");
- emitModuleMemberName(node);
- emitEnd(node);
- write(";");
- }
- if (languageVersion < 2 /* ES6 */ && node.parent === currentSourceFile) {
- emitExportMemberAssignments(node.name);
- }
- }
- function emitEnumMember(node) {
- var enumParent = node.parent;
- emitStart(node);
- write(getGeneratedNameForNode(enumParent));
- write("[");
- write(getGeneratedNameForNode(enumParent));
- write("[");
- emitExpressionForPropertyName(node.name);
- write("] = ");
- writeEnumMemberDeclarationValue(node);
- write("] = ");
- emitExpressionForPropertyName(node.name);
- emitEnd(node);
- write(";");
- }
- function writeEnumMemberDeclarationValue(member) {
- var value = resolver.getConstantValue(member);
- if (value !== undefined) {
- write(value.toString());
- return;
- }
- else if (member.initializer) {
- emit(member.initializer);
- }
- else {
- write("undefined");
- }
- }
- function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) {
- if (moduleDeclaration.body.kind === 205 /* ModuleDeclaration */) {
- var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body);
- return recursiveInnerModule || moduleDeclaration.body;
- }
- }
- function shouldEmitModuleDeclaration(node) {
- return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.separateCompilation);
- }
- function isModuleMergedWithES6Class(node) {
- return languageVersion === 2 /* ES6 */ && !!(resolver.getNodeCheckFlags(node) & 2048 /* LexicalModuleMergesWithClass */);
- }
- function emitModuleDeclaration(node) {
- // Emit only if this module is non-ambient.
- var shouldEmit = shouldEmitModuleDeclaration(node);
- if (!shouldEmit) {
- return emitOnlyPinnedOrTripleSlashComments(node);
- }
- var hoistedInDeclarationScope = isSourceFileLevelDeclarationInSystemExternalModule(node, false);
- var emitVarForModule = !hoistedInDeclarationScope && !isModuleMergedWithES6Class(node);
- if (emitVarForModule) {
- emitStart(node);
- if (isES6ExportedDeclaration(node)) {
- write("export ");
- }
- write("var ");
- emit(node.name);
- write(";");
- emitEnd(node);
- writeLine();
- }
- emitStart(node);
- write("(function (");
- emitStart(node.name);
- write(getGeneratedNameForNode(node));
- emitEnd(node.name);
- write(") ");
- if (node.body.kind === 206 /* ModuleBlock */) {
- var saveTempFlags = tempFlags;
- var saveTempVariables = tempVariables;
- tempFlags = 0;
- tempVariables = undefined;
- emit(node.body);
- tempFlags = saveTempFlags;
- tempVariables = saveTempVariables;
- }
- else {
- write("{");
- increaseIndent();
- scopeEmitStart(node);
- emitCaptureThisForNodeIfNecessary(node);
- writeLine();
- emit(node.body);
- decreaseIndent();
- writeLine();
- var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body;
- emitToken(15 /* CloseBraceToken */, moduleBlock.statements.end);
- scopeEmitEnd();
- }
- write(")(");
- // write moduleDecl = containingModule.m only if it is not exported es6 module member
- if ((node.flags & 1 /* Export */) && !isES6ExportedDeclaration(node)) {
- emit(node.name);
- write(" = ");
- }
- emitModuleMemberName(node);
- write(" || (");
- emitModuleMemberName(node);
- write(" = {}));");
- emitEnd(node);
- if (!isES6ExportedDeclaration(node) && node.name.kind === 65 /* Identifier */ && node.parent === currentSourceFile) {
- if (compilerOptions.module === 3 /* System */ && (node.flags & 1 /* Export */)) {
- writeLine();
- write(exportFunctionForFile + "(\"");
- emitDeclarationName(node);
- write("\", ");
- emitDeclarationName(node);
- write(")");
- }
- emitExportMemberAssignments(node.name);
- }
- }
- function emitRequire(moduleName) {
- if (moduleName.kind === 8 /* StringLiteral */) {
- write("require(");
- emitStart(moduleName);
- emitLiteral(moduleName);
- emitEnd(moduleName);
- emitToken(17 /* CloseParenToken */, moduleName.end);
- }
- else {
- write("require()");
- }
- }
- function getNamespaceDeclarationNode(node) {
- if (node.kind === 208 /* ImportEqualsDeclaration */) {
- return node;
- }
- var importClause = node.importClause;
- if (importClause && importClause.namedBindings && importClause.namedBindings.kind === 211 /* NamespaceImport */) {
- return importClause.namedBindings;
- }
- }
- function isDefaultImport(node) {
- return node.kind === 209 /* ImportDeclaration */ && node.importClause && !!node.importClause.name;
- }
- function emitExportImportAssignments(node) {
- if (ts.isAliasSymbolDeclaration(node) && resolver.isValueAliasDeclaration(node)) {
- emitExportMemberAssignments(node.name);
- }
- ts.forEachChild(node, emitExportImportAssignments);
- }
- function emitImportDeclaration(node) {
- if (languageVersion < 2 /* ES6 */) {
- return emitExternalImportDeclaration(node);
- }
- // ES6 import
- if (node.importClause) {
- var shouldEmitDefaultBindings = resolver.isReferencedAliasDeclaration(node.importClause);
- var shouldEmitNamedBindings = node.importClause.namedBindings && resolver.isReferencedAliasDeclaration(node.importClause.namedBindings, true);
- if (shouldEmitDefaultBindings || shouldEmitNamedBindings) {
- write("import ");
- emitStart(node.importClause);
- if (shouldEmitDefaultBindings) {
- emit(node.importClause.name);
- if (shouldEmitNamedBindings) {
- write(", ");
- }
- }
- if (shouldEmitNamedBindings) {
- emitLeadingComments(node.importClause.namedBindings);
- emitStart(node.importClause.namedBindings);
- if (node.importClause.namedBindings.kind === 211 /* NamespaceImport */) {
- write("* as ");
- emit(node.importClause.namedBindings.name);
- }
- else {
- write("{ ");
- emitExportOrImportSpecifierList(node.importClause.namedBindings.elements, resolver.isReferencedAliasDeclaration);
- write(" }");
- }
- emitEnd(node.importClause.namedBindings);
- emitTrailingComments(node.importClause.namedBindings);
- }
- emitEnd(node.importClause);
- write(" from ");
- emit(node.moduleSpecifier);
- write(";");
- }
- }
- else {
- write("import ");
- emit(node.moduleSpecifier);
- write(";");
- }
- }
- function emitExternalImportDeclaration(node) {
- if (ts.contains(externalImports, node)) {
- var isExportedImport = node.kind === 208 /* ImportEqualsDeclaration */ && (node.flags & 1 /* Export */) !== 0;
- var namespaceDeclaration = getNamespaceDeclarationNode(node);
- if (compilerOptions.module !== 2 /* AMD */) {
- emitLeadingComments(node);
- emitStart(node);
- if (namespaceDeclaration && !isDefaultImport(node)) {
- // import x = require("foo")
- // import * as x from "foo"
- if (!isExportedImport)
- write("var ");
- emitModuleMemberName(namespaceDeclaration);
- write(" = ");
- }
- else {
- // import "foo"
- // import x from "foo"
- // import { x, y } from "foo"
- // import d, * as x from "foo"
- // import d, { x, y } from "foo"
- var isNakedImport = 209 /* ImportDeclaration */ && !node.importClause;
- if (!isNakedImport) {
- write("var ");
- write(getGeneratedNameForNode(node));
- write(" = ");
- }
- }
- emitRequire(ts.getExternalModuleName(node));
- if (namespaceDeclaration && isDefaultImport(node)) {
- // import d, * as x from "foo"
- write(", ");
- emitModuleMemberName(namespaceDeclaration);
- write(" = ");
- write(getGeneratedNameForNode(node));
- }
- write(";");
- emitEnd(node);
- emitExportImportAssignments(node);
- emitTrailingComments(node);
- }
- else {
- if (isExportedImport) {
- emitModuleMemberName(namespaceDeclaration);
- write(" = ");
- emit(namespaceDeclaration.name);
- write(";");
- }
- else if (namespaceDeclaration && isDefaultImport(node)) {
- // import d, * as x from "foo"
- write("var ");
- emitModuleMemberName(namespaceDeclaration);
- write(" = ");
- write(getGeneratedNameForNode(node));
- write(";");
- }
- emitExportImportAssignments(node);
- }
- }
- }
- function emitImportEqualsDeclaration(node) {
- if (ts.isExternalModuleImportEqualsDeclaration(node)) {
- emitExternalImportDeclaration(node);
- return;
- }
- // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when
- // - current file is not external module
- // - import declaration is top level and target is value imported by entity name
- if (resolver.isReferencedAliasDeclaration(node) ||
- (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node))) {
- emitLeadingComments(node);
- emitStart(node);
- if (isES6ExportedDeclaration(node)) {
- write("export ");
- write("var ");
- }
- else if (!(node.flags & 1 /* Export */)) {
- write("var ");
- }
- emitModuleMemberName(node);
- write(" = ");
- emit(node.moduleReference);
- write(";");
- emitEnd(node);
- emitExportImportAssignments(node);
- emitTrailingComments(node);
- }
- }
- function emitExportDeclaration(node) {
- ts.Debug.assert(compilerOptions.module !== 3 /* System */);
- if (languageVersion < 2 /* ES6 */) {
- if (node.moduleSpecifier && (!node.exportClause || resolver.isValueAliasDeclaration(node))) {
- emitStart(node);
- var generatedName = getGeneratedNameForNode(node);
- if (node.exportClause) {
- // export { x, y, ... } from "foo"
- if (compilerOptions.module !== 2 /* AMD */) {
- write("var ");
- write(generatedName);
- write(" = ");
- emitRequire(ts.getExternalModuleName(node));
- write(";");
- }
- for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) {
- var specifier = _a[_i];
- if (resolver.isValueAliasDeclaration(specifier)) {
- writeLine();
- emitStart(specifier);
- emitContainingModuleName(specifier);
- write(".");
- emitNodeWithoutSourceMap(specifier.name);
- write(" = ");
- write(generatedName);
- write(".");
- emitNodeWithoutSourceMap(specifier.propertyName || specifier.name);
- write(";");
- emitEnd(specifier);
- }
- }
- }
- else {
- // export * from "foo"
- writeLine();
- write("__export(");
- if (compilerOptions.module !== 2 /* AMD */) {
- emitRequire(ts.getExternalModuleName(node));
- }
- else {
- write(generatedName);
- }
- write(");");
- }
- emitEnd(node);
- }
- }
- else {
- if (!node.exportClause || resolver.isValueAliasDeclaration(node)) {
- emitStart(node);
- write("export ");
- if (node.exportClause) {
- // export { x, y, ... }
- write("{ ");
- emitExportOrImportSpecifierList(node.exportClause.elements, resolver.isValueAliasDeclaration);
- write(" }");
- }
- else {
- write("*");
- }
- if (node.moduleSpecifier) {
- write(" from ");
- emitNodeWithoutSourceMap(node.moduleSpecifier);
- }
- write(";");
- emitEnd(node);
- }
- }
- }
- function emitExportOrImportSpecifierList(specifiers, shouldEmit) {
- ts.Debug.assert(languageVersion >= 2 /* ES6 */);
- var needsComma = false;
- for (var _i = 0; _i < specifiers.length; _i++) {
- var specifier = specifiers[_i];
- if (shouldEmit(specifier)) {
- if (needsComma) {
- write(", ");
- }
- emitStart(specifier);
- if (specifier.propertyName) {
- emitNodeWithoutSourceMap(specifier.propertyName);
- write(" as ");
- }
- emitNodeWithoutSourceMap(specifier.name);
- emitEnd(specifier);
- needsComma = true;
- }
- }
- }
- function emitExportAssignment(node) {
- if (!node.isExportEquals && resolver.isValueAliasDeclaration(node)) {
- if (languageVersion >= 2 /* ES6 */) {
- writeLine();
- emitStart(node);
- write("export default ");
- var expression = node.expression;
- emit(expression);
- if (expression.kind !== 200 /* FunctionDeclaration */ &&
- expression.kind !== 201 /* ClassDeclaration */) {
- write(";");
- }
- emitEnd(node);
- }
- else {
- writeLine();
- emitStart(node);
- if (compilerOptions.module === 3 /* System */) {
- write(exportFunctionForFile + "(\"default\",");
- emit(node.expression);
- write(")");
- }
- else {
- emitContainingModuleName(node);
- if (languageVersion === 0 /* ES3 */) {
- write("[\"default\"] = ");
- }
- else {
- write(".default = ");
- }
- emit(node.expression);
- }
- write(";");
- emitEnd(node);
- }
- }
- }
- function collectExternalModuleInfo(sourceFile) {
- externalImports = [];
- exportSpecifiers = {};
- exportEquals = undefined;
- hasExportStars = false;
- for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {
- var node = _a[_i];
- switch (node.kind) {
- case 209 /* ImportDeclaration */:
- if (!node.importClause ||
- resolver.isReferencedAliasDeclaration(node.importClause, true)) {
- // import "mod"
- // import x from "mod" where x is referenced
- // import * as x from "mod" where x is referenced
- // import { x, y } from "mod" where at least one import is referenced
- externalImports.push(node);
- }
- break;
- case 208 /* ImportEqualsDeclaration */:
- if (node.moduleReference.kind === 219 /* ExternalModuleReference */ && resolver.isReferencedAliasDeclaration(node)) {
- // import x = require("mod") where x is referenced
- externalImports.push(node);
- }
- break;
- case 215 /* ExportDeclaration */:
- if (node.moduleSpecifier) {
- if (!node.exportClause) {
- // export * from "mod"
- externalImports.push(node);
- hasExportStars = true;
- }
- else if (resolver.isValueAliasDeclaration(node)) {
- // export { x, y } from "mod" where at least one export is a value symbol
- externalImports.push(node);
- }
- }
- else {
- // export { x, y }
- for (var _b = 0, _c = node.exportClause.elements; _b < _c.length; _b++) {
- var specifier = _c[_b];
- var name_6 = (specifier.propertyName || specifier.name).text;
- (exportSpecifiers[name_6] || (exportSpecifiers[name_6] = [])).push(specifier);
- }
- }
- break;
- case 214 /* ExportAssignment */:
- if (node.isExportEquals && !exportEquals) {
- // export = x
- exportEquals = node;
- }
- break;
- }
- }
- }
- function emitExportStarHelper() {
- if (hasExportStars) {
- writeLine();
- write("function __export(m) {");
- increaseIndent();
- writeLine();
- write("for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];");
- decreaseIndent();
- writeLine();
- write("}");
- }
- }
- function getLocalNameForExternalImport(importNode) {
- var namespaceDeclaration = getNamespaceDeclarationNode(importNode);
- if (namespaceDeclaration && !isDefaultImport(importNode)) {
- return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, namespaceDeclaration.name);
- }
- else {
- return getGeneratedNameForNode(importNode);
- }
- }
- function getExternalModuleNameText(importNode) {
- var moduleName = ts.getExternalModuleName(importNode);
- if (moduleName.kind === 8 /* StringLiteral */) {
- return getLiteralText(moduleName);
- }
- return undefined;
- }
- function emitVariableDeclarationsForImports() {
- if (externalImports.length === 0) {
- return;
- }
- writeLine();
- var started = false;
- for (var _i = 0; _i < externalImports.length; _i++) {
- var importNode = externalImports[_i];
- // do not create variable declaration for exports and imports that lack import clause
- var skipNode = importNode.kind === 215 /* ExportDeclaration */ ||
- (importNode.kind === 209 /* ImportDeclaration */ && !importNode.importClause);
- if (skipNode) {
- continue;
- }
- if (!started) {
- write("var ");
- started = true;
- }
- else {
- write(", ");
- }
- write(getLocalNameForExternalImport(importNode));
- }
- if (started) {
- write(";");
- }
- }
- function hoistTopLevelVariableAndFunctionDeclarations(node) {
- // per ES6 spec:
- // 15.2.1.16.4 ModuleDeclarationInstantiation() Concrete Method
- // - var declarations are initialized to undefined - 14.a.ii
- // - function/generator declarations are instantiated - 16.a.iv
- // this means that after module is instantiated but before its evaluation
- // exported functions are already accessible at import sites
- // in theory we should hoist only exported functions and its dependencies
- // in practice to simplify things we'll hoist all source level functions and variable declaration
- // including variables declarations for module and class declarations
- var hoistedVars;
- var hoistedFunctionDeclarations;
- visit(node);
- if (hoistedVars) {
- writeLine();
- write("var ");
- for (var i = 0; i < hoistedVars.length; ++i) {
- var local = hoistedVars[i];
- if (i !== 0) {
- write(", ");
- }
- if (local.kind === 201 /* ClassDeclaration */ || local.kind === 205 /* ModuleDeclaration */) {
- emitDeclarationName(local);
- }
- else {
- emit(local);
- }
- }
- write(";");
- }
- if (hoistedFunctionDeclarations) {
- for (var _i = 0; _i < hoistedFunctionDeclarations.length; _i++) {
- var f = hoistedFunctionDeclarations[_i];
- writeLine();
- emit(f);
- }
- }
- function visit(node) {
- if (node.kind === 200 /* FunctionDeclaration */) {
- if (!hoistedFunctionDeclarations) {
- hoistedFunctionDeclarations = [];
- }
- hoistedFunctionDeclarations.push(node);
- return;
- }
- if (node.kind === 201 /* ClassDeclaration */) {
- // TODO: rename block scoped classes
- if (!hoistedVars) {
- hoistedVars = [];
- }
- hoistedVars.push(node);
- return;
- }
- if (node.kind === 205 /* ModuleDeclaration */ && shouldEmitModuleDeclaration(node)) {
- if (!hoistedVars) {
- hoistedVars = [];
- }
- hoistedVars.push(node);
- return;
- }
- if (node.kind === 198 /* VariableDeclaration */ || node.kind === 152 /* BindingElement */) {
- if (shouldHoistVariable(node, false)) {
- var name_7 = node.name;
- if (name_7.kind === 65 /* Identifier */) {
- if (!hoistedVars) {
- hoistedVars = [];
- }
- hoistedVars.push(name_7);
- }
- else {
- ts.forEachChild(name_7, visit);
- }
- }
- return;
- }
- if (ts.isBindingPattern(node)) {
- ts.forEach(node.elements, visit);
- return;
- }
- if (!ts.isDeclaration(node)) {
- ts.forEachChild(node, visit);
- }
- }
- }
- function shouldHoistVariable(node, checkIfSourceFileLevelDecl) {
- if (checkIfSourceFileLevelDecl && !isSourceFileLevelDeclarationInSystemExternalModule(node, false)) {
- return false;
- }
- // hoist variable if
- // - it is not block scoped
- // - it is top level block scoped
- // if block scoped variables are nested in some another block then
- // no other functions can use them except ones that are defined at least in the same block
- return (ts.getCombinedNodeFlags(node) & 12288 /* BlockScoped */) === 0 ||
- ts.getEnclosingBlockScopeContainer(node).kind === 227 /* SourceFile */;
- }
- function isCurrentFileSystemExternalModule() {
- return compilerOptions.module === 3 /* System */ && ts.isExternalModule(currentSourceFile);
- }
- function emitSystemModuleBody(node, startIndex) {
- // shape of the body in system modules:
- // function (exports) {
- //
- //
- //
- // return {
- // setters: [
- //
- // ],
- // execute: function() {
- //
- // }
- // }
- //
- // }
- // I.e:
- // import {x} from 'file1'
- // var y = 1;
- // export function foo() { return y + x(); }
- // console.log(y);
- // will be transformed to
- // function(exports) {
- // var file1; // local alias
- // var y;
- // function foo() { return y + file1.x(); }
- // exports("foo", foo);
- // return {
- // setters: [
- // function(v) { file1 = v }
- // ],
- // execute(): function() {
- // y = 1;
- // console.log(y);
- // }
- // };
- // }
- emitVariableDeclarationsForImports();
- writeLine();
- hoistTopLevelVariableAndFunctionDeclarations(node);
- writeLine();
- write("return {");
- increaseIndent();
- writeLine();
- emitSetters();
- writeLine();
- emitExecute(node, startIndex);
- emitTempDeclarations(true);
- decreaseIndent();
- writeLine();
- write("}"); // return
- }
- function emitSetters() {
- write("setters:[");
- for (var i = 0; i < externalImports.length; ++i) {
- if (i !== 0) {
- write(",");
- }
- writeLine();
- increaseIndent();
- var importNode = externalImports[i];
- var importVariableName = getLocalNameForExternalImport(importNode) || "";
- var parameterName = "_" + importVariableName;
- write("function (" + parameterName + ") {");
- switch (importNode.kind) {
- case 209 /* ImportDeclaration */:
- if (!importNode.importClause) {
- // 'import "..."' case
- // module is imported only for side-effects, setter body will be empty
- break;
- }
- // fall-through
- case 208 /* ImportEqualsDeclaration */:
- ts.Debug.assert(importVariableName !== "");
- increaseIndent();
- writeLine();
- // save import into the local
- write(importVariableName + " = " + parameterName);
- writeLine();
- var defaultName = importNode.kind === 209 /* ImportDeclaration */
- ? importNode.importClause.name
- : importNode.name;
- if (defaultName) {
- // emit re-export for imported default name
- // import n1 from 'foo1'
- // import n2 = require('foo2')
- // export {n1}
- // export {n2}
- emitExportMemberAssignments(defaultName);
- writeLine();
- }
- if (importNode.kind === 209 /* ImportDeclaration */ &&
- importNode.importClause.namedBindings) {
- var namedBindings = importNode.importClause.namedBindings;
- if (namedBindings.kind === 211 /* NamespaceImport */) {
- // emit re-export for namespace
- // import * as n from 'foo'
- // export {n}
- emitExportMemberAssignments(namedBindings.name);
- writeLine();
- }
- else {
- // emit re-exports for named imports
- // import {a, b} from 'foo'
- // export {a, b as c}
- for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) {
- var element = _a[_i];
- emitExportMemberAssignments(element.name || element.propertyName);
- writeLine();
- }
- }
- }
- decreaseIndent();
- break;
- case 215 /* ExportDeclaration */:
- ts.Debug.assert(importVariableName !== "");
- increaseIndent();
- if (importNode.exportClause) {
- // export {a, b as c} from 'foo'
- // emit as:
- // exports('a', _foo["a"])
- // exports('c', _foo["b"])
- for (var _b = 0, _c = importNode.exportClause.elements; _b < _c.length; _b++) {
- var e = _c[_b];
- writeLine();
- write(exportFunctionForFile + "(\"");
- emitNodeWithoutSourceMap(e.name);
- write("\", " + parameterName + "[\"");
- emitNodeWithoutSourceMap(e.propertyName || e.name);
- write("\"]);");
- }
- }
- else {
- writeLine();
- // export * from 'foo'
- // emit as:
- // for (var n in _foo) exports(n, _foo[n]);
- // NOTE: it is safe to use name 'n' since parameter name always starts with '_'
- write("for (var n in " + parameterName + ") " + exportFunctionForFile + "(n, " + parameterName + "[n]);");
- }
- writeLine();
- decreaseIndent();
- break;
- }
- write("}");
- decreaseIndent();
- }
- write("],");
- }
- function emitExecute(node, startIndex) {
- write("execute: function() {");
- increaseIndent();
- writeLine();
- for (var i = startIndex; i < node.statements.length; ++i) {
- var statement = node.statements[i];
- // - imports/exports are not emitted for system modules
- // - function declarations are not emitted because they were already hoisted
- switch (statement.kind) {
- case 215 /* ExportDeclaration */:
- case 209 /* ImportDeclaration */:
- case 208 /* ImportEqualsDeclaration */:
- case 200 /* FunctionDeclaration */:
- continue;
- }
- writeLine();
- emit(statement);
- }
- decreaseIndent();
- writeLine();
- write("}"); // execute
- }
- function emitSystemModule(node, startIndex) {
- collectExternalModuleInfo(node);
- // System modules has the following shape
- // System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */})
- // 'exports' here is a function 'exports(name: string, value: T): T' that is used to publish exported values.
- // 'exports' returns its 'value' argument so in most cases expressions
- // that mutate exported values can be rewritten as:
- // expr -> exports('name', expr).
- // The only exception in this rule is postfix unary operators,
- // see comment to 'emitPostfixUnaryExpression' for more details
- ts.Debug.assert(!exportFunctionForFile);
- // make sure that name of 'exports' function does not conflict with existing identifiers
- exportFunctionForFile = makeUniqueName("exports");
- write("System.register([");
- for (var i = 0; i < externalImports.length; ++i) {
- var text = getExternalModuleNameText(externalImports[i]);
- if (i !== 0) {
- write(", ");
- }
- write(text);
- }
- write("], function(" + exportFunctionForFile + ") {");
- writeLine();
- increaseIndent();
- emitCaptureThisForNodeIfNecessary(node);
- emitSystemModuleBody(node, startIndex);
- decreaseIndent();
- writeLine();
- write("});");
- }
- function emitAMDModule(node, startIndex) {
- collectExternalModuleInfo(node);
- // An AMD define function has the following shape:
- // define(id?, dependencies?, factory);
- //
- // This has the shape of
- // define(name, ["module1", "module2"], function (module1Alias) {
- // The location of the alias in the parameter list in the factory function needs to
- // match the position of the module name in the dependency list.
- //
- // To ensure this is true in cases of modules with no aliases, e.g.:
- // `import "module"` or ``
- // we need to add modules without alias names to the end of the dependencies list
- var aliasedModuleNames = []; // names of modules with corresponding parameter in the
- // factory function.
- var unaliasedModuleNames = []; // names of modules with no corresponding parameters in
- // factory function.
- var importAliasNames = []; // names of the parameters in the factory function; these
- // parameters need to match the indexes of the corresponding
- // module names in aliasedModuleNames.
- // Fill in amd-dependency tags
- for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) {
- var amdDependency = _a[_i];
- if (amdDependency.name) {
- aliasedModuleNames.push("\"" + amdDependency.path + "\"");
- importAliasNames.push(amdDependency.name);
- }
- else {
- unaliasedModuleNames.push("\"" + amdDependency.path + "\"");
- }
- }
- for (var _b = 0; _b < externalImports.length; _b++) {
- var importNode = externalImports[_b];
- // Find the name of the external module
- var externalModuleName = getExternalModuleNameText(importNode);
- // Find the name of the module alias, if there is one
- var importAliasName = getLocalNameForExternalImport(importNode);
- if (importAliasName) {
- aliasedModuleNames.push(externalModuleName);
- importAliasNames.push(importAliasName);
- }
- else {
- unaliasedModuleNames.push(externalModuleName);
- }
- }
- writeLine();
- write("define(");
- if (node.amdModuleName) {
- write("\"" + node.amdModuleName + "\", ");
- }
- write("[\"require\", \"exports\"");
- if (aliasedModuleNames.length) {
- write(", ");
- write(aliasedModuleNames.join(", "));
- }
- if (unaliasedModuleNames.length) {
- write(", ");
- write(unaliasedModuleNames.join(", "));
- }
- write("], function (require, exports");
- if (importAliasNames.length) {
- write(", ");
- write(importAliasNames.join(", "));
- }
- write(") {");
- increaseIndent();
- emitExportStarHelper();
- emitCaptureThisForNodeIfNecessary(node);
- emitLinesStartingAt(node.statements, startIndex);
- emitTempDeclarations(true);
- emitExportEquals(true);
- decreaseIndent();
- writeLine();
- write("});");
- }
- function emitCommonJSModule(node, startIndex) {
- collectExternalModuleInfo(node);
- emitExportStarHelper();
- emitCaptureThisForNodeIfNecessary(node);
- emitLinesStartingAt(node.statements, startIndex);
- emitTempDeclarations(true);
- emitExportEquals(false);
- }
- function emitES6Module(node, startIndex) {
- externalImports = undefined;
- exportSpecifiers = undefined;
- exportEquals = undefined;
- hasExportStars = false;
- emitCaptureThisForNodeIfNecessary(node);
- emitLinesStartingAt(node.statements, startIndex);
- emitTempDeclarations(true);
- // Emit exportDefault if it exists will happen as part
- // or normal statement emit.
- }
- function emitExportEquals(emitAsReturn) {
- if (exportEquals && resolver.isValueAliasDeclaration(exportEquals)) {
- writeLine();
- emitStart(exportEquals);
- write(emitAsReturn ? "return " : "module.exports = ");
- emit(exportEquals.expression);
- write(";");
- emitEnd(exportEquals);
- }
- }
- function emitDirectivePrologues(statements, startWithNewLine) {
- for (var i = 0; i < statements.length; ++i) {
- if (ts.isPrologueDirective(statements[i])) {
- if (startWithNewLine || i > 0) {
- writeLine();
- }
- emit(statements[i]);
- }
- else {
- // return index of the first non prologue directive
- return i;
- }
- }
- return statements.length;
- }
- function writeLines(text) {
- var lines = text.split(/\r\n|\r|\n/g);
- for (var i = 0; i < lines.length; ++i) {
- var line = lines[i];
- if (line.length) {
- writeLine();
- write(line);
- }
- }
- }
- function emitSourceFileNode(node) {
- // Start new file on new line
- writeLine();
- emitDetachedComments(node);
- // emit prologue directives prior to __extends
- var startIndex = emitDirectivePrologues(node.statements, false);
- // Only Emit __extends function when target ES5.
- // For target ES6 and above, we can emit classDeclaration as is.
- if ((languageVersion < 2 /* ES6 */) && (!extendsEmitted && resolver.getNodeCheckFlags(node) & 8 /* EmitExtends */)) {
- writeLines(extendsHelper);
- extendsEmitted = true;
- }
- if (!decorateEmitted && resolver.getNodeCheckFlags(node) & 512 /* EmitDecorate */) {
- writeLines(decorateHelper);
- if (compilerOptions.emitDecoratorMetadata) {
- writeLines(metadataHelper);
- }
- decorateEmitted = true;
- }
- if (!paramEmitted && resolver.getNodeCheckFlags(node) & 1024 /* EmitParam */) {
- writeLines(paramHelper);
- paramEmitted = true;
- }
- if (ts.isExternalModule(node)) {
- if (languageVersion >= 2 /* ES6 */) {
- emitES6Module(node, startIndex);
- }
- else if (compilerOptions.module === 2 /* AMD */) {
- emitAMDModule(node, startIndex);
- }
- else if (compilerOptions.module === 3 /* System */) {
- emitSystemModule(node, startIndex);
- }
- else {
- emitCommonJSModule(node, startIndex);
- }
- }
- else {
- externalImports = undefined;
- exportSpecifiers = undefined;
- exportEquals = undefined;
- hasExportStars = false;
- emitCaptureThisForNodeIfNecessary(node);
- emitLinesStartingAt(node.statements, startIndex);
- emitTempDeclarations(true);
- }
- emitLeadingComments(node.endOfFileToken);
- }
- function emitNodeWithoutSourceMap(node, allowGeneratedIdentifiers) {
- if (!node) {
- return;
- }
- if (node.flags & 2 /* Ambient */) {
- return emitOnlyPinnedOrTripleSlashComments(node);
- }
- var emitComments = shouldEmitLeadingAndTrailingComments(node);
- if (emitComments) {
- emitLeadingComments(node);
- }
- emitJavaScriptWorker(node, allowGeneratedIdentifiers);
- if (emitComments) {
- emitTrailingComments(node);
- }
- }
- function shouldEmitLeadingAndTrailingComments(node) {
- switch (node.kind) {
- // All of these entities are emitted in a specialized fashion. As such, we allow
- // the specialized methods for each to handle the comments on the nodes.
- case 202 /* InterfaceDeclaration */:
- case 200 /* FunctionDeclaration */:
- case 209 /* ImportDeclaration */:
- case 208 /* ImportEqualsDeclaration */:
- case 203 /* TypeAliasDeclaration */:
- case 214 /* ExportAssignment */:
- return false;
- case 205 /* ModuleDeclaration */:
- // Only emit the leading/trailing comments for a module if we're actually
- // emitting the module as well.
- return shouldEmitModuleDeclaration(node);
- case 204 /* EnumDeclaration */:
- // Only emit the leading/trailing comments for an enum if we're actually
- // emitting the module as well.
- return shouldEmitEnumDeclaration(node);
- }
- // If this is the expression body of an arrow function that we're down-leveling,
- // then we don't want to emit comments when we emit the body. It will have already
- // been taken care of when we emitted the 'return' statement for the function
- // expression body.
- if (node.kind !== 179 /* Block */ &&
- node.parent &&
- node.parent.kind === 163 /* ArrowFunction */ &&
- node.parent.body === node &&
- compilerOptions.target <= 1 /* ES5 */) {
- return false;
- }
- // Emit comments for everything else.
- return true;
- }
- function emitJavaScriptWorker(node, allowGeneratedIdentifiers) {
- if (allowGeneratedIdentifiers === void 0) { allowGeneratedIdentifiers = true; }
- // Check if the node can be emitted regardless of the ScriptTarget
- switch (node.kind) {
- case 65 /* Identifier */:
- return emitIdentifier(node, allowGeneratedIdentifiers);
- case 129 /* Parameter */:
- return emitParameter(node);
- case 134 /* MethodDeclaration */:
- case 133 /* MethodSignature */:
- return emitMethod(node);
- case 136 /* GetAccessor */:
- case 137 /* SetAccessor */:
- return emitAccessor(node);
- case 93 /* ThisKeyword */:
- return emitThis(node);
- case 91 /* SuperKeyword */:
- return emitSuper(node);
- case 89 /* NullKeyword */:
- return write("null");
- case 95 /* TrueKeyword */:
- return write("true");
- case 80 /* FalseKeyword */:
- return write("false");
- case 7 /* NumericLiteral */:
- case 8 /* StringLiteral */:
- case 9 /* RegularExpressionLiteral */:
- case 10 /* NoSubstitutionTemplateLiteral */:
- case 11 /* TemplateHead */:
- case 12 /* TemplateMiddle */:
- case 13 /* TemplateTail */:
- return emitLiteral(node);
- case 171 /* TemplateExpression */:
- return emitTemplateExpression(node);
- case 176 /* TemplateSpan */:
- return emitTemplateSpan(node);
- case 126 /* QualifiedName */:
- return emitQualifiedName(node);
- case 150 /* ObjectBindingPattern */:
- return emitObjectBindingPattern(node);
- case 151 /* ArrayBindingPattern */:
- return emitArrayBindingPattern(node);
- case 152 /* BindingElement */:
- return emitBindingElement(node);
- case 153 /* ArrayLiteralExpression */:
- return emitArrayLiteral(node);
- case 154 /* ObjectLiteralExpression */:
- return emitObjectLiteral(node);
- case 224 /* PropertyAssignment */:
- return emitPropertyAssignment(node);
- case 225 /* ShorthandPropertyAssignment */:
- return emitShorthandPropertyAssignment(node);
- case 127 /* ComputedPropertyName */:
- return emitComputedPropertyName(node);
- case 155 /* PropertyAccessExpression */:
- return emitPropertyAccess(node);
- case 156 /* ElementAccessExpression */:
- return emitIndexedAccess(node);
- case 157 /* CallExpression */:
- return emitCallExpression(node);
- case 158 /* NewExpression */:
- return emitNewExpression(node);
- case 159 /* TaggedTemplateExpression */:
- return emitTaggedTemplateExpression(node);
- case 160 /* TypeAssertionExpression */:
- return emit(node.expression);
- case 161 /* ParenthesizedExpression */:
- return emitParenExpression(node);
- case 200 /* FunctionDeclaration */:
- case 162 /* FunctionExpression */:
- case 163 /* ArrowFunction */:
- return emitFunctionDeclaration(node);
- case 164 /* DeleteExpression */:
- return emitDeleteExpression(node);
- case 165 /* TypeOfExpression */:
- return emitTypeOfExpression(node);
- case 166 /* VoidExpression */:
- return emitVoidExpression(node);
- case 167 /* PrefixUnaryExpression */:
- return emitPrefixUnaryExpression(node);
- case 168 /* PostfixUnaryExpression */:
- return emitPostfixUnaryExpression(node);
- case 169 /* BinaryExpression */:
- return emitBinaryExpression(node);
- case 170 /* ConditionalExpression */:
- return emitConditionalExpression(node);
- case 173 /* SpreadElementExpression */:
- return emitSpreadElementExpression(node);
- case 172 /* YieldExpression */:
- return emitYieldExpression(node);
- case 175 /* OmittedExpression */:
- return;
- case 179 /* Block */:
- case 206 /* ModuleBlock */:
- return emitBlock(node);
- case 180 /* VariableStatement */:
- return emitVariableStatement(node);
- case 181 /* EmptyStatement */:
- return write(";");
- case 182 /* ExpressionStatement */:
- return emitExpressionStatement(node);
- case 183 /* IfStatement */:
- return emitIfStatement(node);
- case 184 /* DoStatement */:
- return emitDoStatement(node);
- case 185 /* WhileStatement */:
- return emitWhileStatement(node);
- case 186 /* ForStatement */:
- return emitForStatement(node);
- case 188 /* ForOfStatement */:
- case 187 /* ForInStatement */:
- return emitForInOrForOfStatement(node);
- case 189 /* ContinueStatement */:
- case 190 /* BreakStatement */:
- return emitBreakOrContinueStatement(node);
- case 191 /* ReturnStatement */:
- return emitReturnStatement(node);
- case 192 /* WithStatement */:
- return emitWithStatement(node);
- case 193 /* SwitchStatement */:
- return emitSwitchStatement(node);
- case 220 /* CaseClause */:
- case 221 /* DefaultClause */:
- return emitCaseOrDefaultClause(node);
- case 194 /* LabeledStatement */:
- return emitLabelledStatement(node);
- case 195 /* ThrowStatement */:
- return emitThrowStatement(node);
- case 196 /* TryStatement */:
- return emitTryStatement(node);
- case 223 /* CatchClause */:
- return emitCatchClause(node);
- case 197 /* DebuggerStatement */:
- return emitDebuggerStatement(node);
- case 198 /* VariableDeclaration */:
- return emitVariableDeclaration(node);
- case 174 /* ClassExpression */:
- return emitClassExpression(node);
- case 201 /* ClassDeclaration */:
- return emitClassDeclaration(node);
- case 202 /* InterfaceDeclaration */:
- return emitInterfaceDeclaration(node);
- case 204 /* EnumDeclaration */:
- return emitEnumDeclaration(node);
- case 226 /* EnumMember */:
- return emitEnumMember(node);
- case 205 /* ModuleDeclaration */:
- return emitModuleDeclaration(node);
- case 209 /* ImportDeclaration */:
- return emitImportDeclaration(node);
- case 208 /* ImportEqualsDeclaration */:
- return emitImportEqualsDeclaration(node);
- case 215 /* ExportDeclaration */:
- return emitExportDeclaration(node);
- case 214 /* ExportAssignment */:
- return emitExportAssignment(node);
- case 227 /* SourceFile */:
- return emitSourceFileNode(node);
- }
- }
- function hasDetachedComments(pos) {
- return detachedCommentsInfo !== undefined && lastOrUndefined(detachedCommentsInfo).nodePos === pos;
- }
- function getLeadingCommentsWithoutDetachedComments() {
- // get the leading comments from detachedPos
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos);
- if (detachedCommentsInfo.length - 1) {
- detachedCommentsInfo.pop();
- }
- else {
- detachedCommentsInfo = undefined;
- }
- return leadingComments;
- }
- function filterComments(ranges, onlyPinnedOrTripleSlashComments) {
- // If we're removing comments, then we want to strip out all but the pinned or
- // triple slash comments.
- if (ranges && onlyPinnedOrTripleSlashComments) {
- ranges = ts.filter(ranges, isPinnedOrTripleSlashComment);
- if (ranges.length === 0) {
- return undefined;
- }
- }
- return ranges;
- }
- function getLeadingCommentsToEmit(node) {
- // Emit the leading comments only if the parent's pos doesn't match because parent should take care of emitting these comments
- if (node.parent) {
- if (node.parent.kind === 227 /* SourceFile */ || node.pos !== node.parent.pos) {
- if (hasDetachedComments(node.pos)) {
- // get comments without detached comments
- return getLeadingCommentsWithoutDetachedComments();
- }
- else {
- // get the leading comments from the node
- return ts.getLeadingCommentRangesOfNode(node, currentSourceFile);
- }
- }
- }
- }
- function getTrailingCommentsToEmit(node) {
- // Emit the trailing comments only if the parent's pos doesn't match because parent should take care of emitting these comments
- if (node.parent) {
- if (node.parent.kind === 227 /* SourceFile */ || node.end !== node.parent.end) {
- return ts.getTrailingCommentRanges(currentSourceFile.text, node.end);
- }
- }
- }
- function emitOnlyPinnedOrTripleSlashComments(node) {
- emitLeadingCommentsWorker(node, true);
- }
- function emitLeadingComments(node) {
- return emitLeadingCommentsWorker(node, compilerOptions.removeComments);
- }
- function emitLeadingCommentsWorker(node, onlyPinnedOrTripleSlashComments) {
- // If the caller only wants pinned or triple slash comments, then always filter
- // down to that set. Otherwise, filter based on the current compiler options.
- var leadingComments = filterComments(getLeadingCommentsToEmit(node), onlyPinnedOrTripleSlashComments);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
- }
- function emitTrailingComments(node) {
- // Emit the trailing comments only if the parent's end doesn't match
- var trailingComments = filterComments(getTrailingCommentsToEmit(node), compilerOptions.removeComments);
- // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment*/
- ts.emitComments(currentSourceFile, writer, trailingComments, false, newLine, writeComment);
- }
- function emitLeadingCommentsOfPosition(pos) {
- var leadingComments;
- if (hasDetachedComments(pos)) {
- // get comments without detached comments
- leadingComments = getLeadingCommentsWithoutDetachedComments();
- }
- else {
- // get the leading comments from the node
- leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, pos);
- }
- leadingComments = filterComments(leadingComments, compilerOptions.removeComments);
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, { pos: pos, end: pos }, leadingComments);
- // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space
- ts.emitComments(currentSourceFile, writer, leadingComments, true, newLine, writeComment);
- }
- function emitDetachedComments(node) {
- var leadingComments = ts.getLeadingCommentRanges(currentSourceFile.text, node.pos);
- if (leadingComments) {
- var detachedComments = [];
- var lastComment;
- ts.forEach(leadingComments, function (comment) {
- if (lastComment) {
- var lastCommentLine = ts.getLineOfLocalPosition(currentSourceFile, lastComment.end);
- var commentLine = ts.getLineOfLocalPosition(currentSourceFile, comment.pos);
- if (commentLine >= lastCommentLine + 2) {
- // There was a blank line between the last comment and this comment. This
- // comment is not part of the copyright comments. Return what we have so
- // far.
- return detachedComments;
- }
- }
- detachedComments.push(comment);
- lastComment = comment;
- });
- if (detachedComments.length) {
- // All comments look like they could have been part of the copyright header. Make
- // sure there is at least one blank line between it and the node. If not, it's not
- // a copyright header.
- var lastCommentLine = ts.getLineOfLocalPosition(currentSourceFile, lastOrUndefined(detachedComments).end);
- var nodeLine = ts.getLineOfLocalPosition(currentSourceFile, ts.skipTrivia(currentSourceFile.text, node.pos));
- if (nodeLine >= lastCommentLine + 2) {
- // Valid detachedComments
- ts.emitNewLineBeforeLeadingComments(currentSourceFile, writer, node, leadingComments);
- ts.emitComments(currentSourceFile, writer, detachedComments, true, newLine, writeComment);
- var currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: lastOrUndefined(detachedComments).end };
- if (detachedCommentsInfo) {
- detachedCommentsInfo.push(currentDetachedCommentInfo);
- }
- else {
- detachedCommentsInfo = [currentDetachedCommentInfo];
- }
- }
- }
- }
- }
- function isPinnedOrTripleSlashComment(comment) {
- if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 42 /* asterisk */) {
- return currentSourceFile.text.charCodeAt(comment.pos + 2) === 33 /* exclamation */;
- }
- else if (currentSourceFile.text.charCodeAt(comment.pos + 1) === 47 /* slash */ &&
- comment.pos + 2 < comment.end &&
- currentSourceFile.text.charCodeAt(comment.pos + 2) === 47 /* slash */ &&
- currentSourceFile.text.substring(comment.pos, comment.end).match(ts.fullTripleSlashReferencePathRegEx)) {
- return true;
- }
- }
- }
- function emitFile(jsFilePath, sourceFile) {
- emitJavaScript(jsFilePath, sourceFile);
- if (compilerOptions.declaration) {
- ts.writeDeclarationFile(jsFilePath, sourceFile, host, resolver, diagnostics);
- }
- }
- }
- ts.emitFiles = emitFiles;
-})(ts || (ts = {}));